title: How to use a package of generated protobuf inside a go module?
body: <p>I encounter an issue with Go Module management and a generation of protobuffers (using go1.16, protoc-gen-go@latest).</p>
  <p>I have this project structure:</p>
  <pre><code>subproj
  ├── go.mod         (module company.tld/proj/subproj)
  ├── subproj.go     (entry point : package main)
  ├── proto          (folder containing .proto files)
  ├── packageFolder
  |   └── file1.go   (package packageFolder)
  └── Makefile       (used to generate *.pb.go and build subproj binary)
  </code></pre>
  <p>The <em>proto</em> folder is used by other projects (obviously...) (via git submodule).<br />
  Protos are like the following:</p>
  <pre class="lang-proto prettyprint-override"><code>syntax = &quot;proto3&quot;
  option csharp_namespace = &quot;Proj.Proto&quot;;
  option go_package = &quot;company.tld/proj/projpb&quot;;
  package entity.proj
  ...
  </code></pre>
  <p>because of different version of messages, few protobuffer files need to be in another &quot;namespace&quot;:</p>
  <pre class="lang-proto prettyprint-override"><code>option go_package = &quot;company.tld/proj/projpb/other&quot;;
  package entity.proj.other
  </code></pre>
  <p>In my Makefile, I tried to generate the right *.pb.go at the right place:</p>
  <pre><code># Proto sources
  PROTO= $(wildcard ${PROTODIR}/*.proto)
  PBGO=  $(PROTO:.proto=.pb.go)
  
  MODULE_NAME=company.tld/proj
  GO_OPT_FLAG=   --go_opt=module=${MODULE_NAME}     
  GRPC_OPT_FLAG= --go-grpc_opt=module=${MODULE_NAME}
  #GO_OPT_FLAG=   --go_opt=paths=import
  #GRPC_OPT_FLAG= --go-grpc_opt=paths=import
  
  .PHONY: clean install proto
  
  ## Builds the project
  build: proto
      go build ${LDFLAGS} -o ${BINARY}
  
  $(PROTOBUF_GO_PLUGIN):
      go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
  
  $(GRPC_GO_PLUGIN):
      go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
  
  %.pb.go: %.proto | $(PROTOBUF_GO_PLUGIN) $(GRPC_GO_PLUGIN)
      protoc --proto_path=${PROTODIR} --go_out=. ${GO_OPT_FLAG} --go-grpc_out=. ${GRPC_OPT_FLAG} $&lt;
  
  proto: $(PBGO)
  </code></pre>
  <p>So, depending on the option used with the protoc compiler:<br />
  → With <code>--go_opt=paths=import</code></p>
  <p>A folder tree <em>company.tld/proj/projpb</em> is created by protoc at the project's root. Each object is in a package called <em>projpb</em> or <em>other</em>, in the subpackage other.</p>
  <p>Generated Proto objects, that include the <em>other</em> namespace-d objects, have the import path <code>import other &quot;company.tld/proj/projpb/other&quot;</code> (which is brought by the <code>go_package</code> option, but which is wrong because it is not an existing module - go mod tidy/vendor is complaining that it cannot find it).</p>
  <p>Normal project files need the following import path to reach the Generated Proto objects :<br />
  <code>import pb &quot;company.tld/proj/subproj/company.tld/proj/projpb&quot;</code><br />
  which seems odd and not the proper way to do.</p>
  <p>→ With <code>--go_opt=module=company.tld/proj</code></p>
  <p>A folder <em>projpb</em> is created by protoc at the project's root and each generated .pb.go has the package <em>projpb</em> or <em>other</em>, in the subpackage other.</p>
  <p>Generated Proto objects, that include the <em>other</em> namespace-d objects, still have the import path <code>import other &quot;company.tld/proj/projpb/other&quot;</code> (which is still brought by the <code>go_package</code> option and is still wrong because this is still a non-existing module - these are generated files... why would I want to create a module of these ?).</p>
  <p>The cool thing is that with this go_opt, accessing generated types looks much more normal with<br />
  <code>import pb &quot;company.tld/proj/subproj/projpb&quot;</code>.</p>
  <p>Finally, I tried</p>
  <ul>
  <li>using local import path on the go_package option in the .proto files (that is refused on build time, because there would be an <code>import other &quot;./projpb/other&quot;</code> in generated protobuffer object)</li>
  <li>to use the <em>replace</em> instruction in the go.mod file like this :</li>
  </ul>
  <pre><code>replace (
      company.tld/proj/projpb =&gt; ./projpb
      company.tld/proj/projpb/other =&gt; ./projpb/other
  )
  </code></pre>
  <p>(but go mod tidy/vendor is complaining that it cannot find the go.mod file inside the generated folder ./projpb)</p>
  <p>Has someone encountered a similar problem? Or am I missing a command option to tell to Go, «I generate protobuffer objects in a package, or package in a package, and I simply want to use them. They are not a module, so please, provide the right import paths to the generated object and let me use them in my code».</p>
  <hr />
  <p>[Update 01]<br />
  I gave a try to the <code>go_opt=paths=source_relative</code> (inspired by this <a href="https://stackoverflow.com/a/62540631/7135482">ticket</a>).<br />
  I created the folder in the Makefile, protoc generates files inside.<br />
  Notes:</p>
  <ul>
  <li>generated protos use the full path, specified with the <code>go_package</code> option, to relate to one another.</li>
  <li>As long as <code>go_package</code> option needs a full path, Go (go mod tidy/vendor) will want to search for a go.mod file inside the created folder, containing generated protos.</li>
  </ul>
  <p>What is the correct way to tell Go that I am not looking for a Module, yet still satisfy the go_package option's full path constraint in the protobuffer file ?</p>