I have read official docs & tutorial online about protobuf but I still don't quite understand the relationship between the package name & import path in proto definition and actual directory structure.
To make my question clear, let's say this is my project structure:
root
├── project
│ └── protos
│ ├── common
│ │ └── common.proto
│ └── custom
│ ├── app.proto
│ └── util
│ └── util.proto
common.proto
syntax = "proto3";
// how should I decide the package for this file based on my project structure?
package project.protos.common;
message Common {
// ...
}
app.proto, which references common.proto (in another separate directory) and util.proto (in subdirectory)
syntax = "proto3";
package project.protos.custom;
import "project/protos/common/common.proto";
import "project/protos/custom/util/util.proto";
import "google/protobuf/timestamp.proto";
message App {
project.protos.common.Common common = 3;
project.protos.custom.util.Util util = 4;
}
util.proto
syntax = "proto3";
package project.protos.custom.util;
option java_multiple_files = true;
message Util {
// ...
}
After doing several trials, it turns out that if I run the protoc command at the root directory, using the command:
protoc -I . --java_out=. project/protos/**/*.proto
then imports are working correctly and every proto file is compiled with no error. However, let's say if I run the protoc not at root directory, but at subdirectory project, using similar command:
protoc -I . --java_out=. protos/**/*.proto
Compilation would then fail with following error:
project/protos/common/common.proto: File not found.
project/protos/custom/util/util.proto: File not found.
protos/custom/app.proto:6:1: Import "project/protos/common/common.proto" was not found or had errors.
protos/custom/app.proto:8:1: Import "project/protos/custom/util/util.proto" was not found or had errors.
protos/custom/app.proto:19:5: "project.protos.common.Common" seems to be defined in "protos/common/common.proto", which is not imported by "protos/custom/app.proto". To use it here, please add the necessary import.
protos/custom/app.proto:20:5: "project.protos.custom.util.Util" is not defined.
As I'm working with Java for most of times, I'm currently thinking the way that how package & import works in protobuf, with respect to the actual directory structure, is similar to how package & import works in Java, with respect to classpath.
That is, if I want to compile a proto with package specified to be "project.protos.common", then I should run the protoc command on the parent directory of project dir, where project/protos/common is a valid path.
Similarly, if I am importing a proto in another proto file with the import path set to be "project/protos/custom/util/util.proto", then I should also make sure that from the directory when I run protoc command, path project/protos/custom/util/util.proto is present.
I'm currently guessing whatever path we feed into -I option, protoc will treat them in the same way as Java classpath or python search path. Upon importing, protoc will look for the imported file on every specified -I path, following the relative path that is indicated by import statement.
However, after searching online for similar questions and reading some articles, now I have the impression that package and import in protobuf are actually much more flexible than I thought them to be. Is my understanding wrong here?