Search code examples
protocol-buffers

protocol-buffers: fully qualified import names


While reading https://developers.google.com/protocol-buffers/docs/proto I ran into the following piece of text:

The protocol compiler searches for imported files in a set of directories specified on the protocol compiler command line using the -I/--proto_path flag. If no flag was given, it looks in the directory in which the compiler was invoked. In general you should set the --proto_path flag to the root of your project and use fully qualified names for all imports.

What exactly do they mean that --proto_path should point at the root of the project, and use fully-qualified import names?

For example my project tree has the following structure:

$HOME/
    my_project/
       docs/
       src/
       lib/
       proto/
         p1.proto
         p2.proto

proto is where I keep .proto schemas. So for the above layout I should call protoc as --proto_path=$HOME/my_project/proto ? Not sure what should import look like?


Solution

  • Yes --proto_path=$HOME/my_project/proto and you should try this to prove it to yourself.

    There are 2 "paths" that are important and I think I've not seen it documented:

    1. the proto_path(s) which are the path(s) on the local file system to the root (!) of the import path of protos
    2. the import paths extending from the proto_path(s) to specific proto files.

    Extending your example. If you wanted to namespace the protos foo.protobuf such that p1.proto and p2.proto included package foo.protobuf;, p1.proto and p2.proto would need to be placed in subdirectory foo/protobuf beneath my_project/proto and the proto_path would be unchanged.

    This can be seen with Google's Well-Known Types. These are in protoc/include alongside protoc/bin and each proto is in the subdirectory google/protobuf because each e.g. Any is package google.protobuf;.

    Unfortunately (!) the well-known types are confusingly (usually) not included in proto_path because they are in a (well-)known location for protoc. However, they are implicitly (and you can explicitly references them as) --proto_path=/path/to/protoc/include