compileAndFindResponseDescriptor compiles all compileNames (+ imports via roots) and returns serviceFull.method Output desc. We avoid building a separate registry; instead we search the linked files directly.
(compileNames []string, roots []string, serviceFull, method string)
| 157 | // compileAndFindResponseDescriptor compiles all compileNames (+ imports via roots) and returns serviceFull.method Output desc. |
| 158 | // We avoid building a separate registry; instead we search the linked files directly. |
| 159 | func compileAndFindResponseDescriptor(compileNames []string, roots []string, serviceFull, method string) (protoreflect.MessageDescriptor, []protoreflect.FileDescriptor, error) { |
| 160 | c := &protocompile.Compiler{ |
| 161 | Resolver: &protocompile.SourceResolver{ImportPaths: roots}, |
| 162 | Reporter: reporter.NewReporter( |
| 163 | func(e reporter.ErrorWithPos) error { return e }, // errors |
| 164 | func(w reporter.ErrorWithPos) { /* optionally log warnings */ }, |
| 165 | ), |
| 166 | } |
| 167 | |
| 168 | ctx, cancel := context.WithTimeout(context.Background(), 45*time.Second) |
| 169 | defer cancel() |
| 170 | |
| 171 | files, err := c.Compile(ctx, compileNames...) |
| 172 | if err != nil { |
| 173 | return nil, nil, fmt.Errorf("compile %v (relative to -I: %v): %w", compileNames, roots, err) |
| 174 | } |
| 175 | if len(files) == 0 { |
| 176 | return nil, nil, fmt.Errorf("no files compiled for %v", compileNames) |
| 177 | } |
| 178 | |
| 179 | // Directly search the linked files for the service, then the method. |
| 180 | full := protoreflect.FullName(serviceFull) |
| 181 | for _, f := range files { |
| 182 | d := f.FindDescriptorByName(full) |
| 183 | if d == nil { |
| 184 | continue |
| 185 | } |
| 186 | |
| 187 | sd, ok := d.(protoreflect.ServiceDescriptor) |
| 188 | if !ok { |
| 189 | continue |
| 190 | } |
| 191 | |
| 192 | for i := range sd.Methods().Len() { |
| 193 | m := sd.Methods().Get(i) |
| 194 | if string(m.Name()) == method { |
| 195 | // Convert linker.Files to []protoreflect.FileDescriptor |
| 196 | fileDescs := make([]protoreflect.FileDescriptor, len(files)) |
| 197 | for i, f := range files { |
| 198 | fileDescs[i] = f |
| 199 | } |
| 200 | return m.Output(), fileDescs, nil |
| 201 | } |
| 202 | } |
| 203 | return nil, nil, fmt.Errorf("method %q not found on service %q", method, serviceFull) |
| 204 | } |
| 205 | |
| 206 | return nil, nil, fmt.Errorf("service %q not found in compiled set", serviceFull) |
| 207 | } |
| 208 | |
| 209 | func mustAbs(p string) (string, error) { |
| 210 | if p == "" { |
no test coverage detected