jvolkman / intellij-protobuf-editor

Protocol Buffers for IntelliJ-based IDEs
Apache License 2.0
122 stars 15 forks source link

Cannot resolve imports #25

Open Pilvinen opened 4 years ago

Pilvinen commented 4 years ago

There seems to be a problem with the plugin showing incorrectly that imports were not resolved even though they are:

image

image

Everything is working just fine and the imported file is available and found in the folder.

I can compile it no problem with this import line. It's just the editor which is incorrectly showing it red and giving "Cannot resolve imports."

To double confirm if I change the name of the file to something incorrect - it then fails to compile. If I change it back it compiles just fine.

Ie. it seems to be a Protocol Buffer Editor problem.

I am using Rider 2020.1.4 on Ubuntu Linux and I have Protocol Buffer Editor version 2.0.

Thank you for your continued development and support of this crucial plugin. Stay safe and healthy.

jvolkman commented 4 years ago

Hi, Please refer to this section in the readme that talks about import path settings. The editor doesn't assume that imports are in the same directory. You can either add that directory as a project source root, or add it to the list of import paths in the Protocol Buffer language settings as the readme describes.

Pilvinen commented 4 years ago

After quick Googling it does not appear that Rider and .NET platform has the concept of "project source root" that Java and IntelliJ IDEA has. I know what you mean, but I can't find anything like that in the IDE and Googling for it didn't come up with anything useful.

Next I took a look at your alternative suggestion of Protocol Buffer Import path settings. By default mine looks like this:

image

It doesn't exactly look like something that's inviting me to fiddle with it, so I won't touch it. I don't understand what it's supposed to do and that default path looks very funky to me and nothing like in the examples. I read the readme section about path settings ~6 times carefully and... I'm not really none the wiser for it. Maybe it's a Java vs. dotNET thing or maybe I'm just stupid, I don't know.

I'm not sure what you mean by "editor doesn't assume that the imports are in the same directory" either - it doesn't really matter what directory the proto files are at. It doesn't work as I would expect it to work even if they are at another folder. Defining the path does absolutely nothing. I even get auto-suggestions for the path and file names - from your plugin I would assume - and for a moment there everything is OK, but then the path turns red again.

Intuitively - as an end user - since I have a path in the import-statement, I would just simply expect the plugin to work.

I don't know how it works under the hood - or why - but if I have a perfectly functional import statement defined I would just simply expect it to work without jumping through any additional hoops. There's probably some really good technical reason why it doesn't work like that which is beyond my current understanding.

But, as it stands, the easiest option in my Rider and .NET environment would simply seem to be uninstalling this plugin.

I only wanted the plugin for syntax highlighting and syntax parsing since the IDE automatically suggested to me, I was like "Hm? Ok, I'll click install", and obviously it's not doing that for me correctly out of the box - for whatever reason.

So, if this is a "not-going-to-fix" (or can't fix because of X) issue for you, then I'm just simply going to uninstall the plugin to get rid of the incorrect and annoying red highlights.

In case you are interested in refactoring your code in some sensible fashion so that it just works, let me know. I'm happy to test it for you. And if not, no harm done.

Peace.

jvolkman commented 4 years ago

I haven't used Rider and didn't realize that it doesn't have the concept of "source roots". That certainly makes the current situation confusing since 1) there won't be any import paths configured by default (except for that weird one that you saw), and 2) the import path configuration is even more unfriendly than usual.

For reference, the default settings for one of my projects in IntelliJ look like this: image

The single import that does exist in your list contains some of the protobuf "well known type" files such as descriptor.proto, timestamp.proto, any.proto, etc., in an attempt to make imports of these files work by default.

The good news is that the fix should be as easy as adding your Protocols directory path to that list. You'll need to uncheck "Configure automatically" first. If you don't want to do that, there's not much else that will fix the missing import problem for you at the moment.

I'm going to guess that you compiled your .proto files by running protoc from within your Protocols directory. Something like this:

$ pwd
/tmp/issue_25_example/Protocols
$ protoc --csharp_out=. *.proto                  
$ ls
Destinations.cs     Destinations.proto  NetworkPacket.cs    NetworkPacket.proto

It works! And it probably looks like you can import files from within the same directory with only the filename. But that's not actually the common case. protoc has the concept of an import path which defaults to the current directory, so imports of files within the directory that you run the compiler from will work. But if you try to run from a different directory, you'll get an error:

$ cd ..
$ pwd
/tmp/issue_25_example
$ protoc --csharp_out=Protocols Protocols/*.proto
Destinations.proto: File not found.
Protocols/NetworkPacket.proto: Import "Destinations.proto" was not found or had errors.
Protocols/NetworkPacket.proto:7:5: "Venom.Destination" seems to be defined in "Protocols/Destinations.proto", which is not imported by "Protocols/NetworkPacket.proto".  To use it here, please add the necessary import.

The import path can be changed from the default working directory by using the --proto_path parameter:

$ pwd
/tmp/issue_25_example
$ protoc --csharp_out=Protocols --proto_path=Protocols Protocols/*.proto
$ ls Protocols/
Destinations.cs     Destinations.proto  NetworkPacket.cs    NetworkPacket.proto

The path settings panel is the equivalent of the --proto_path parameter. It makes a guess that the project's source roots would be the appropriate default paths, but this is often not correct and, in the case of Rider, can't be correct, as we've discovered.

There's not a single solution that will work for everyone, unfortunately. At least not one that I've found. But I'm certainly open to suggestions.

I have some thoughts on how to make the path settings more useful/friendly. And it probably makes sense to pick different defaults for IntelliJ vs. Rider. For now, i'll add a note to the readme that things are a bit broken for Rider.

shawnlu96 commented 4 years ago

I haven't used Rider and didn't realize that it doesn't have the concept of "source roots". That certainly makes the current situation confusing since 1) there won't be any import paths configured by default (except for that weird one that you saw), and 2) the import path configuration is even more unfriendly than usual.

For reference, the default settings for one of my projects in IntelliJ look like this: image

The single import that does exist in your list contains some of the protobuf "well known type" files such as descriptor.proto, timestamp.proto, any.proto, etc., in an attempt to make imports of these files work by default.

The good news is that the fix should be as easy as adding your Protocols directory path to that list. You'll need to uncheck "Configure automatically" first. If you don't want to do that, there's not much else that will fix the missing import problem for you at the moment.

I'm going to guess that you compiled your .proto files by running protoc from within your Protocols directory. Something like this:

$ pwd
/tmp/issue_25_example/Protocols
$ protoc --csharp_out=. *.proto                  
$ ls
Destinations.cs     Destinations.proto  NetworkPacket.cs    NetworkPacket.proto

It works! And it probably looks like you can import files from within the same directory with only the filename. But that's not actually the common case. protoc has the concept of an import path which defaults to the current directory, so imports of files within the directory that you run the compiler from will work. But if you try to run from a different directory, you'll get an error:

$ cd ..
$ pwd
/tmp/issue_25_example
$ protoc --csharp_out=Protocols Protocols/*.proto
Destinations.proto: File not found.
Protocols/NetworkPacket.proto: Import "Destinations.proto" was not found or had errors.
Protocols/NetworkPacket.proto:7:5: "Venom.Destination" seems to be defined in "Protocols/Destinations.proto", which is not imported by "Protocols/NetworkPacket.proto".  To use it here, please add the necessary import.

The import path can be changed from the default working directory by using the --proto_path parameter:

$ pwd
/tmp/issue_25_example
$ protoc --csharp_out=Protocols --proto_path=Protocols Protocols/*.proto
$ ls Protocols/
Destinations.cs     Destinations.proto  NetworkPacket.cs    NetworkPacket.proto

The path settings panel is the equivalent of the --proto_path parameter. It makes a guess that the project's source roots would be the appropriate default paths, but this is often not correct and, in the case of Rider, can't be correct, as we've discovered.

There's not a single solution that will work for everyone, unfortunately. At least not one that I've found. But I'm certainly open to suggestions.

I have some thoughts on how to make the path settings more useful/friendly. And it probably makes sense to pick different defaults for IntelliJ vs. Rider. For now, i'll add a note to the readme that things are a bit broken for Rider.

@jvolkman Could the default proto paths be loaded from the *.csproj files for C# projects? It seems that the ProtoRoot property could be defined within it. (found that in this documentation), not really sure about that, just one naive guess)

jvolkman commented 4 years ago

Certainly if that's a popular convention in C# projects it could be used as a hint.

RayMMond commented 4 years ago

@jvolkman yes it is a popular convention, can you please implement it?

RayMMond commented 4 years ago

The good news is that the fix should be as easy as adding your Protocols directory path to that list. You'll need to uncheck "Configure automatically" first. If you don't want to do that, there's not much else that will fix the missing import problem for you at the moment.

@jvolkman And adding my directory path to the list just isn't working. image

jvolkman commented 4 years ago

@RayMMond it looks like you may be missing file:// at the beginning of that path. If you double click the one above it to enter edit mode, you should notice the file:// prefix. And if you click the + button and add a path using the file dialog, that prefix should be included.

RayMMond commented 4 years ago

@RayMMond it looks like you may be missing file:// at the beginning of that path. If you double click the one above it to enter edit mode, you should notice the file:// prefix. And if you click the + button and add a path using the file dialog, that prefix should be included.

Yes.. It works after adding file:// prefix. Thanks a lot~~ 😄

wxw310415 commented 4 years ago

I haven't used Rider and didn't realize that it doesn't have the concept of "source roots". That certainly makes the current situation confusing since 1) there won't be any import paths configured by default (except for that weird one that you saw), and 2) the import path configuration is even more unfriendly than usual.

For reference, the default settings for one of my projects in IntelliJ look like this: image

The single import that does exist in your list contains some of the protobuf "well known type" files such as descriptor.proto, timestamp.proto, any.proto, etc., in an attempt to make imports of these files work by default.

The good news is that the fix should be as easy as adding your Protocols directory path to that list. You'll need to uncheck "Configure automatically" first. If you don't want to do that, there's not much else that will fix the missing import problem for you at the moment.

I'm going to guess that you compiled your .proto files by running protoc from within your Protocols directory. Something like this:

$ pwd
/tmp/issue_25_example/Protocols
$ protoc --csharp_out=. *.proto                  
$ ls
Destinations.cs     Destinations.proto  NetworkPacket.cs    NetworkPacket.proto

It works! And it probably looks like you can import files from within the same directory with only the filename. But that's not actually the common case. protoc has the concept of an import path which defaults to the current directory, so imports of files within the directory that you run the compiler from will work. But if you try to run from a different directory, you'll get an error:

$ cd ..
$ pwd
/tmp/issue_25_example
$ protoc --csharp_out=Protocols Protocols/*.proto
Destinations.proto: File not found.
Protocols/NetworkPacket.proto: Import "Destinations.proto" was not found or had errors.
Protocols/NetworkPacket.proto:7:5: "Venom.Destination" seems to be defined in "Protocols/Destinations.proto", which is not imported by "Protocols/NetworkPacket.proto".  To use it here, please add the necessary import.

The import path can be changed from the default working directory by using the --proto_path parameter:

$ pwd
/tmp/issue_25_example
$ protoc --csharp_out=Protocols --proto_path=Protocols Protocols/*.proto
$ ls Protocols/
Destinations.cs     Destinations.proto  NetworkPacket.cs    NetworkPacket.proto

The path settings panel is the equivalent of the --proto_path parameter. It makes a guess that the project's source roots would be the appropriate default paths, but this is often not correct and, in the case of Rider, can't be correct, as we've discovered.

There's not a single solution that will work for everyone, unfortunately. At least not one that I've found. But I'm certainly open to suggestions.

I have some thoughts on how to make the path settings more useful/friendly. And it probably makes sense to pick different defaults for IntelliJ vs. Rider. For now, i'll add a note to the readme that things are a bit broken for Rider.

谢谢 !终于解决了这个问题~ Thanks 😝

rolatsch commented 3 years ago

Webstorm has this problem too. It seems like there are only absolute paths supported as import paths. This not very useful when project configuration is shared via version control. Is it possible to allow the configuration of import paths relative to the project root?

Marvvyn commented 3 years ago

A bit broken is not quite correct. I don't even get the syntax highlighting, just white text, strings and errors. The Import Paths does not allow me to add any path. It opens a dialog which requires to select a file, but whatever I select, nothing is added to the import paths.

image

jvolkman commented 3 years ago

Which editor version is this @Marvvyn? Does your color scheme make numbers red, or are those also errors?

Marvvyn commented 3 years ago

Yes, I use red for numbers, so that's not an error. My settings for protobuf:

image

Editor version:

image

Kyle-sandeman-mrdfood commented 3 years ago

I completely disagree with "current directory is not searched" I installed this plugin today and "configure automatically" seems to require you to manually mark proto directories.

Imagine your C compiler telling you #include "example.h" is invalid because you didn't provide it in the INCLUDE environment variable

xirius commented 3 years ago

The good news is that the fix should be as easy as adding your Protocols directory path to that list. You'll need to uncheck "Configure automatically" first. If you don't want to do that, there's not much else that will fix the missing import problem for you at the moment.

For me even that doesn't work! I click the "+" button, it opens "Select Path" dialog but it forces me to chose a specific file. Ok, I chose the file and click "Open". Dialog closes but nothing is added to the list! Nothing! Tried everything, no way to add new entries in the list :(

Protocol Buffer Editor: 2.1.0 JetBrains Rider 2020.2.4 Build #RD-202.7660.16, built on September 30, 2020

jvolkman commented 3 years ago

@xirius I'll see if I can reproduce with the versions you've listed. I haven't heard of that behavior. What OS are you using?

One way that you may be able to work around that: 1) In protobuf settings, uncheck "Configure automatically" 2) Exit Rider 3) Find your project configuration area. For me, using IntelliJ, it's in the project directory in a subdirectory named .idea. In that directory, there should be a file named protoeditor.xml. 4) Add a new ImportPathEntry element to the file.

Here's what mine looks like:

<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ProtobufLanguageSettings">
    <option name="autoConfigEnabled" value="false" />
    <option name="importPathEntries">
      <list>
        <ImportPathEntry>
          <option name="location" value="file://$PROJECT_DIR$" />
        </ImportPathEntry>
        <ImportPathEntry>
          <option name="location" value="jar://$APPLICATION_PLUGINS_DIR$/protobuf-editor.jar!/include" />
        </ImportPathEntry>
      </list>
    </option>
    <option name="descriptorPath" value="google/protobuf/descriptor.proto" />
  </component>
</project>
Marvvyn commented 3 years ago

@xirius I'll see if I can reproduce with the versions you've listed. I haven't heard of that behavior. What OS are you using?

I have the same issue. However this workaround helps a little bit. I still don't see the colors that I set in the rider for proto files but at least the errors are gone now.

EDIT: It does not not ignore color settings completely. I can change color of numbers, strings, etc. Keywords always use the color of identifiers.

jvolkman commented 3 years ago

@Marvvyn do error annotations work? For example, a field name or number specified twice?

Marvvyn commented 3 years ago

@jvolkman yes they work.

puppiesaroundtheworld commented 3 years ago

Behavior:

Same as xirius / Marvvyn; whereby some proto references were missing and attempting to add the folder location through the settings required me to find a file. When said file was clicked, the application would return to the previous settings window with no new values added.

Manually editing the project files to add the root folder of the project (edited after further research) resulted in the new folder reference to appear in the settings and for the references to be picked up in the code, removing the errors I was getting before. Syntax coloring does work for me, and was prior to the changes for the file. Only syntax errors indicated a potential issue.

Edit: While working on a solution, adding the folder of the project with the *.proto file folder structure fixes lookup references while working within the solution context.

Context:

Manually added .proto files to project in order to support gRPC over HTTP in .NET Core. Added .proto files in a created google/api folder. When importing these references into my own *.proto files, attempts to reference google.api.http caused an error to be highlighted in the editor on the api portion of google.api.http.

References were picked up by build tools / Visual Studio 2019 Community and the service would run correctly. Only errors appeared to be highlights in Rider.

Similarly manually added *.proto files in a protobuf subfolder to support timestamp and wrappers did not throw errors and worked flawlessly even before the Project files editing. It's possible these are already in the jar file that comes with the plugin?

IDE info:

JetBrains Rider 2020.3.2 Build #RD-203.6682.21, built on December 29, 2020 (licensing / sub snipped) Runtime version: 11.0.9.1+11-b1145.63 amd64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o. .NET Framework 4.0.30319.42000 Windows 10 10.0 GC: ParNew, ConcurrentMarkSweep Memory: 1450M Cores: 16 Registry: debugger.new.debug.tool.window.view=true, ide.tree.horizontal.default.autoscrolling=false, performance.watcher.sampling.interval.ms=200, ide.borderless.tab.caption.in.title=false, ide.tooltip.showAllSeverities=true, show.diff.preview.as.editor.tab=true, ide.mac.bigsur.alerts.enabled=false, debugger.show.values.use.inlays=false, light.edit.file.open.enabled=false, performance.watcher.unresponsive.interval.ms=1000, ide.tree.expand.navigatable.on.double.click.disabled=true, search.everywhere.settings=true, show.diff.preview.as.editor.tab.with.single.click=true, parameter.info.max.visible.rows=10, ide.win.file.chooser.native=true, vcs.log.show.diff.preview.as.editor.tab=true, search.everywhere.pattern.checking=false, ide.tooltip.initialDelay=0, ide.balloon.shadow.size=0, ide.require.transaction.for.model.changes=false, ide.debug.in.title=true, ide.new.project.model=false, rdclient.asyncActions=false Non-Bundled Plugins: com.intellij.resharper.HeapAllocationsViewer, com.intellij.resharper.StructuredLogging, com.jetbrains.darkPurpleTheme, com.samdark.intellij-visual-studio-code-dark-plus, com.vecheslav.darculaDarkerTheme, idea.plugin.protoeditor, nb-mind-map-idea, com.microsoft.vso.idea, com.jetbrains.rider.android, aws.toolkit

Default value of importPathEntries after the plugin installation. This did not change whether autoConfigEnabled was on or not, file://$PROJECT_DIR$ was not present.

<option name="importPathEntries">
  <list>
    <ImportPathEntry>
      <option name="location" value="jar://$APPLICATION_PLUGINS_DIR$/protobuf-editor.jar!/include" />
    </ImportPathEntry>
  </list>
</option>
michaeldboyd commented 3 years ago

Here's how I fixed this. (Rider 2020.3.3 on MacOS 11.1)

As long as I use the relative path from the selected directory, I'm able to resolve my imports within Rider.

Thanks for the great plugin, @jvolkman

Ihavesoul commented 3 years ago

Well, actually - default imports still doesn't work in Rider)

HuseynBurhonov commented 2 years ago

What to do for disappearing red errors in proto?