Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
9f2dd3ed35 | |||
|
8e89b899d8 | ||
2dc9459eb8 | |||
b2f5437d6e | |||
b002cbb491 | |||
6b8fa89a69 | |||
|
8d4aac8b8b | ||
fc763a645d | |||
2ef183d1b4 | |||
77f66dc9c5 | |||
c29702ad77 | |||
764fa7111d |
24
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
24
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: For reporting bugs in go-micro
|
||||||
|
title: "[BUG]"
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
|
||||||
|
1. What are you trying to do?
|
||||||
|
2. What did you expect to happen?
|
||||||
|
3. What happens instead?
|
||||||
|
|
||||||
|
**How to reproduce the bug:**
|
||||||
|
|
||||||
|
If possible, please include a minimal code snippet here.
|
||||||
|
|
||||||
|
**Environment:**
|
||||||
|
Go Version: please paste `go version` output here
|
||||||
|
```
|
||||||
|
please paste `go env` output here
|
||||||
|
```
|
17
.github/ISSUE_TEMPLATE/feature-request---enhancement.md
vendored
Normal file
17
.github/ISSUE_TEMPLATE/feature-request---enhancement.md
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
name: Feature request / Enhancement
|
||||||
|
about: If you have a need not served by go-micro
|
||||||
|
title: "[FEATURE]"
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
14
.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
14
.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
name: Question
|
||||||
|
about: Ask a question about go-micro
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Before asking, please check if your question has already been answered:
|
||||||
|
|
||||||
|
1. Check the documentation - https://micro.mu/docs/
|
||||||
|
2. Check the examples and plugins - https://github.com/micro/examples & https://github.com/micro/go-plugins
|
||||||
|
3. Search existing issues
|
9
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
9
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
## Pull Request template
|
||||||
|
Please, go through these steps before clicking submit on this PR.
|
||||||
|
|
||||||
|
1. Give a descriptive title to your PR.
|
||||||
|
2. Provide a description of your changes.
|
||||||
|
3. Make sure you have some relevant tests.
|
||||||
|
4. Put `closes #XXXX` in your comment to auto-close the issue that your PR fixes (if applicable).
|
||||||
|
|
||||||
|
**PLEASE REMOVE THIS TEMPLATE BEFORE SUBMITTING**
|
20
.github/renovate.json
vendored
Normal file
20
.github/renovate.json
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"extends": [
|
||||||
|
"config:base"
|
||||||
|
],
|
||||||
|
"postUpdateOptions": ["gomodTidy"],
|
||||||
|
"packageRules": [
|
||||||
|
{
|
||||||
|
"matchUpdateTypes": ["minor", "patch", "pin", "digest"],
|
||||||
|
"automerge": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"groupName": "all deps",
|
||||||
|
"separateMajorMinor": true,
|
||||||
|
"groupSlug": "all",
|
||||||
|
"packagePatterns": [
|
||||||
|
"*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
46
.github/workflows/build.yml
vendored
Normal file
46
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
name: build
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
name: test
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: setup
|
||||||
|
uses: actions/setup-go@v2
|
||||||
|
with:
|
||||||
|
go-version: 1.16
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: cache
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ~/go/pkg/mod
|
||||||
|
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||||
|
restore-keys: ${{ runner.os }}-go-
|
||||||
|
- name: deps
|
||||||
|
run: go get -v -t -d ./...
|
||||||
|
- name: test
|
||||||
|
env:
|
||||||
|
INTEGRATION_TESTS: yes
|
||||||
|
run: go test -mod readonly -v ./...
|
||||||
|
lint:
|
||||||
|
name: lint
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: lint
|
||||||
|
uses: golangci/golangci-lint-action@v2
|
||||||
|
continue-on-error: true
|
||||||
|
with:
|
||||||
|
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
|
||||||
|
version: v1.30
|
||||||
|
# Optional: working directory, useful for monorepos
|
||||||
|
# working-directory: somedir
|
||||||
|
# Optional: golangci-lint command line arguments.
|
||||||
|
# args: --issues-exit-code=0
|
||||||
|
# Optional: show only new issues if it's a pull request. The default value is `false`.
|
||||||
|
# only-new-issues: true
|
46
.github/workflows/pr.yml
vendored
Normal file
46
.github/workflows/pr.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
name: prbuild
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
name: test
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: setup
|
||||||
|
uses: actions/setup-go@v2
|
||||||
|
with:
|
||||||
|
go-version: 1.16
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: cache
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ~/go/pkg/mod
|
||||||
|
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||||
|
restore-keys: ${{ runner.os }}-go-
|
||||||
|
- name: deps
|
||||||
|
run: go get -v -t -d ./...
|
||||||
|
- name: test
|
||||||
|
env:
|
||||||
|
INTEGRATION_TESTS: yes
|
||||||
|
run: go test -mod readonly -v ./...
|
||||||
|
lint:
|
||||||
|
name: lint
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: lint
|
||||||
|
uses: golangci/golangci-lint-action@v2
|
||||||
|
continue-on-error: true
|
||||||
|
with:
|
||||||
|
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
|
||||||
|
version: v1.30
|
||||||
|
# Optional: working directory, useful for monorepos
|
||||||
|
# working-directory: somedir
|
||||||
|
# Optional: golangci-lint command line arguments.
|
||||||
|
# args: --issues-exit-code=0
|
||||||
|
# Optional: show only new issues if it's a pull request. The default value is `false`.
|
||||||
|
# only-new-issues: true
|
203
LICENSE
203
LICENSE
@@ -1,22 +1,191 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2021 Unistack LLC
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
1. Definitions.
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
copies or substantial portions of the Software.
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
the copyright owner that is granting the License.
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
other entities that control, are controlled by, or are under common
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
control with that entity. For the purposes of this definition,
|
||||||
SOFTWARE.
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
Copyright 2021 Unistack LLC.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
25
README.md
Normal file
25
README.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# `protoc-gen-micro`
|
||||||
|
protobuf plugin to generate helper code for micro framework
|
||||||
|
|
||||||
|
A generic **code**/script/data generator based on [Protobuf](https://developers.google.com/protocol-buffers/).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
This project is a generator plugin for the Google Protocol Buffers compiler (`protoc`).
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```console
|
||||||
|
$> protoc --micro_out=debug=true,components="micro|http":. input.proto
|
||||||
|
```
|
||||||
|
|
||||||
|
| Option | Default Value | Accepted Values | Description
|
||||||
|
|-----------------------|---------------|---------------------------|-----------------------
|
||||||
|
| `debug` | *false* | `true` or `false` | if *true*, `protoc` will generate a more verbose output
|
||||||
|
| `components` | `micro` | `micro rpc http chi gorilla` | some values cant coexists like gorilla/chi or rpc/http, values must be concatinated with pipe symbol
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
* Install the **go** compiler and tools from https://golang.org/doc/install
|
||||||
|
* Install **protoc-gen-go**: `go get google.golang.org/protobuf/cmd/protoc-gen-go`
|
||||||
|
* Install **protoc-gen-micro**: `go get github.com/unistack-org/protoc-gen-micro/v3`
|
48
chi.go
48
chi.go
@@ -23,52 +23,54 @@ func (g *Generator) chiGenerate(component string, plugin *protogen.Plugin) error
|
|||||||
|
|
||||||
chiPackageFiles[file.GoPackageName] = struct{}{}
|
chiPackageFiles[file.GoPackageName] = struct{}{}
|
||||||
gname := "micro" + "_" + component + ".pb.go"
|
gname := "micro" + "_" + component + ".pb.go"
|
||||||
gfile := plugin.NewGeneratedFile(gname, ".")
|
|
||||||
|
path := file.GoImportPath
|
||||||
|
if g.standalone {
|
||||||
|
path = "."
|
||||||
|
}
|
||||||
|
gfile := plugin.NewGeneratedFile(gname, path)
|
||||||
|
|
||||||
gfile.P("// Code generated by protoc-gen-micro")
|
gfile.P("// Code generated by protoc-gen-micro")
|
||||||
gfile.P("package ", file.GoPackageName)
|
gfile.P("package ", file.GoPackageName)
|
||||||
|
gfile.P()
|
||||||
|
|
||||||
gfile.P()
|
gfile.Import(contextPackage)
|
||||||
gfile.P("import (")
|
gfile.Import(fmtPackage)
|
||||||
gfile.P(`"context"`)
|
gfile.Import(httpPackage)
|
||||||
gfile.P(`"fmt"`)
|
gfile.Import(reflectPackage)
|
||||||
gfile.P(`"net/http"`)
|
gfile.Import(stringsPackage)
|
||||||
gfile.P(`"reflect"`)
|
gfile.Import(chiPackage)
|
||||||
gfile.P(`"strings"`)
|
gfile.Import(chiMiddlewarePackage)
|
||||||
gfile.P(`chi "github.com/go-chi/chi/v4"`)
|
gfile.Import(microApiPackage)
|
||||||
gfile.P(`middleware "github.com/go-chi/chi/v4/middleware"`)
|
|
||||||
gfile.P(`micro_api "github.com/unistack-org/micro/v3/api"`)
|
|
||||||
gfile.P(")")
|
|
||||||
gfile.P()
|
|
||||||
|
|
||||||
gfile.P("type routeKey struct{}")
|
gfile.P("type routeKey struct{}")
|
||||||
|
|
||||||
gfile.P("func RouteName(ctx context.Context) (string, bool) {")
|
gfile.P("func RouteName(ctx ", contextPackage.Ident("Context"), ") (string, bool) {")
|
||||||
gfile.P("value, ok := ctx.Value(routeKey{}).(string)")
|
gfile.P("value, ok := ctx.Value(routeKey{}).(string)")
|
||||||
gfile.P("return value, ok")
|
gfile.P("return value, ok")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P()
|
gfile.P()
|
||||||
gfile.P("func RegisterHandlers(r *chi.Mux, h interface{}, eps []*micro_api.Endpoint) error {")
|
gfile.P("func RegisterHandlers(r *", chiPackage.Ident("Mux"), ", h interface{}, eps []*", microApiPackage.Ident("Endpoint"), ") error {")
|
||||||
gfile.P("v := reflect.ValueOf(h)")
|
gfile.P("v := ", reflectPackage.Ident("ValueOf"), "(h)")
|
||||||
gfile.P("if v.NumMethod() < 1 {")
|
gfile.P("if v.NumMethod() < 1 {")
|
||||||
gfile.P(`return fmt.Errorf("handler has no methods: %T", h)`)
|
gfile.P(`return `, fmtPackage.Ident("Errorf"), `("handler has no methods: %T", h)`)
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P("for _, ep := range eps {")
|
gfile.P("for _, ep := range eps {")
|
||||||
gfile.P(`idx := strings.Index(ep.Name, ".")`)
|
gfile.P(`idx := `, stringsPackage.Ident("Index"), `(ep.Name, ".")`)
|
||||||
gfile.P("if idx < 1 || len(ep.Name) <= idx {")
|
gfile.P("if idx < 1 || len(ep.Name) <= idx {")
|
||||||
gfile.P(`return fmt.Errorf("invalid api.Endpoint name: %s", ep.Name)`)
|
gfile.P(`return `, fmtPackage.Ident("Errorf"), `("invalid `, microApiPackage.Ident("Endpoint"), ` name: %s", ep.Name)`)
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P("name := ep.Name[idx+1:]")
|
gfile.P("name := ep.Name[idx+1:]")
|
||||||
gfile.P("m := v.MethodByName(name)")
|
gfile.P("m := v.MethodByName(name)")
|
||||||
gfile.P("if !m.IsValid() || m.IsZero() {")
|
gfile.P("if !m.IsValid() || m.IsZero() {")
|
||||||
gfile.P(`return fmt.Errorf("invalid handler, method %s not found", name)`)
|
gfile.P(`return `, fmtPackage.Ident("Errorf"), `("invalid handler, method %s not found", name)`)
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P("rh, ok := m.Interface().(func(http.ResponseWriter, *http.Request))")
|
gfile.P("rh, ok := m.Interface().(func(", httpPackage.Ident("ResponseWriter"), ", *", httpPackage.Ident("Request"), "))")
|
||||||
gfile.P("if !ok {")
|
gfile.P("if !ok {")
|
||||||
gfile.P(`return fmt.Errorf("invalid handler: %#+v", m.Interface())`)
|
gfile.P(`return `, fmtPackage.Ident("Errorf"), `("invalid handler: %#+v", m.Interface())`)
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P("for _, method := range ep.Method {")
|
gfile.P("for _, method := range ep.Method {")
|
||||||
gfile.P("r.With(middleware.WithValue(routeKey{}, ep.Name)).MethodFunc(method, ep.Path[0], rh)")
|
gfile.P("r.With(", chiMiddlewarePackage.Ident("WithValue"), "(routeKey{}, ep.Name)).MethodFunc(method, ep.Path[0], rh)")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P("return nil")
|
gfile.P("return nil")
|
||||||
|
2
go.mod
2
go.mod
@@ -4,6 +4,6 @@ go 1.16
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.2.0
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.2.0
|
||||||
google.golang.org/genproto v0.0.0-20210207032614-bba0dbe2a9ea
|
google.golang.org/genproto v0.0.0-20210224155714-063164c882e6
|
||||||
google.golang.org/protobuf v1.25.0
|
google.golang.org/protobuf v1.25.0
|
||||||
)
|
)
|
||||||
|
3
go.sum
3
go.sum
@@ -331,8 +331,9 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc
|
|||||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20210207032614-bba0dbe2a9ea h1:N98SvVh7Hdle2lgUVFuIkf0B3u29CUakMUQa7Hwz8Wc=
|
|
||||||
google.golang.org/genproto v0.0.0-20210207032614-bba0dbe2a9ea/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20210207032614-bba0dbe2a9ea/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
|
google.golang.org/genproto v0.0.0-20210224155714-063164c882e6 h1:bXUwz2WkXXrXgiLxww3vWmoSHLOGv4ipdPdTvKymcKw=
|
||||||
|
google.golang.org/genproto v0.0.0-20210224155714-063164c882e6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||||
|
39
gorilla.go
39
gorilla.go
@@ -23,41 +23,42 @@ func (g *Generator) gorillaGenerate(component string, plugin *protogen.Plugin) e
|
|||||||
|
|
||||||
gorillaPackageFiles[file.GoPackageName] = struct{}{}
|
gorillaPackageFiles[file.GoPackageName] = struct{}{}
|
||||||
gname := "micro" + "_" + component + ".pb.go"
|
gname := "micro" + "_" + component + ".pb.go"
|
||||||
gfile := plugin.NewGeneratedFile(gname, ".")
|
|
||||||
|
path := file.GoImportPath
|
||||||
|
if g.standalone {
|
||||||
|
path = "."
|
||||||
|
}
|
||||||
|
gfile := plugin.NewGeneratedFile(gname, path)
|
||||||
|
|
||||||
gfile.P("// Code generated by protoc-gen-micro")
|
gfile.P("// Code generated by protoc-gen-micro")
|
||||||
gfile.P("package ", file.GoPackageName)
|
gfile.P("package ", file.GoPackageName)
|
||||||
gfile.P()
|
gfile.P()
|
||||||
|
|
||||||
gfile.P("import (")
|
gfile.Import(fmtPackage)
|
||||||
gfile.P(`"fmt"`)
|
gfile.Import(httpPackage)
|
||||||
gfile.P(`"net/http"`)
|
gfile.Import(reflectPackage)
|
||||||
gfile.P(`"reflect"`)
|
gfile.Import(stringsPackage)
|
||||||
gfile.P(`"strings"`)
|
gfile.Import(microApiPackage)
|
||||||
gfile.P()
|
gfile.Import(gorillaMuxPackage)
|
||||||
gfile.P(`micro_api "github.com/unistack-org/micro/v3/api"`)
|
|
||||||
gfile.P(`mux "github.com/gorilla/mux"`)
|
|
||||||
gfile.P(")")
|
|
||||||
gfile.P()
|
|
||||||
|
|
||||||
gfile.P("func RegisterHandlers(r *mux.Router, h interface{}, eps []*micro_api.Endpoint) error {")
|
gfile.P("func RegisterHandlers(r *", gorillaMuxPackage.Ident("Router"), ", h interface{}, eps []*", microApiPackage.Ident("Endpoint"), ") error {")
|
||||||
gfile.P("v := reflect.ValueOf(h)")
|
gfile.P("v := ", reflectPackage.Ident("ValueOf"), "(h)")
|
||||||
gfile.P("if v.NumMethod() < 1 {")
|
gfile.P("if v.NumMethod() < 1 {")
|
||||||
gfile.P(`return fmt.Errorf("handler has no methods: %T", h)`)
|
gfile.P(`return `, fmtPackage.Ident("Errorf"), `("handler has no methods: %T", h)`)
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P("for _, ep := range eps {")
|
gfile.P("for _, ep := range eps {")
|
||||||
gfile.P(`idx := strings.Index(ep.Name, ".")`)
|
gfile.P(`idx := `, stringsPackage.Ident("Index"), `(ep.Name, ".")`)
|
||||||
gfile.P("if idx < 1 || len(ep.Name) <= idx {")
|
gfile.P("if idx < 1 || len(ep.Name) <= idx {")
|
||||||
gfile.P(`return fmt.Errorf("invalid api.Endpoint name: %s", ep.Name)`)
|
gfile.P(`return `, fmtPackage.Ident("Errorf"), `("invalid `, microApiPackage.Ident("Endpoint"), ` name: %s", ep.Name)`)
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P("name := ep.Name[idx+1:]")
|
gfile.P("name := ep.Name[idx+1:]")
|
||||||
gfile.P("m := v.MethodByName(name)")
|
gfile.P("m := v.MethodByName(name)")
|
||||||
gfile.P("if !m.IsValid() || m.IsZero() {")
|
gfile.P("if !m.IsValid() || m.IsZero() {")
|
||||||
gfile.P(`return fmt.Errorf("invalid handler, method %s not found", name)`)
|
gfile.P(`return `, fmtPackage.Ident("Errorf"), `("invalid handler, method %s not found", name)`)
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P("rh, ok := m.Interface().(func(http.ResponseWriter, *http.Request))")
|
gfile.P("rh, ok := m.Interface().(func(", httpPackage.Ident("ResponseWriter"), ", *", httpPackage.Ident("Request"), "))")
|
||||||
gfile.P("if !ok {")
|
gfile.P("if !ok {")
|
||||||
gfile.P(`return fmt.Errorf("invalid handler: %#+v", m.Interface())`)
|
gfile.P(`return `, fmtPackage.Ident("Errorf"), `("invalid handler: %#+v", m.Interface())`)
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P("r.HandleFunc(ep.Path[0], rh).Methods(ep.Method...).Name(ep.Name)")
|
gfile.P("r.HandleFunc(ep.Path[0], rh).Methods(ep.Method...).Name(ep.Name)")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
|
113
http.go
113
http.go
@@ -1,21 +1,10 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
|
||||||
|
|
||||||
openapi_options "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options"
|
|
||||||
"google.golang.org/protobuf/compiler/protogen"
|
"google.golang.org/protobuf/compiler/protogen"
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Error struct {
|
|
||||||
packageName string
|
|
||||||
types []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Generator) httpGenerate(component string, plugin *protogen.Plugin) error {
|
func (g *Generator) httpGenerate(component string, plugin *protogen.Plugin) error {
|
||||||
errors := make(map[string]struct{})
|
|
||||||
|
|
||||||
for _, file := range plugin.Files {
|
for _, file := range plugin.Files {
|
||||||
if !file.Generate {
|
if !file.Generate {
|
||||||
continue
|
continue
|
||||||
@@ -25,31 +14,22 @@ func (g *Generator) httpGenerate(component string, plugin *protogen.Plugin) erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
gname := file.GeneratedFilenamePrefix + "_micro_" + component + ".pb.go"
|
gname := file.GeneratedFilenamePrefix + "_micro_" + component + ".pb.go"
|
||||||
gfile := plugin.NewGeneratedFile(gname, ".")
|
path := file.GoImportPath
|
||||||
|
if g.standalone {
|
||||||
|
path = "."
|
||||||
|
}
|
||||||
|
gfile := plugin.NewGeneratedFile(gname, path)
|
||||||
|
|
||||||
gfile.P("// Code generated by protoc-gen-micro")
|
gfile.P("// Code generated by protoc-gen-micro")
|
||||||
gfile.P("// source: ", *file.Proto.Name)
|
gfile.P("// source: ", *file.Proto.Name)
|
||||||
gfile.P("package ", file.GoPackageName)
|
gfile.P("package ", file.GoPackageName)
|
||||||
|
|
||||||
gfile.P()
|
|
||||||
gfile.P("import (")
|
|
||||||
gfile.P(`"context"`)
|
|
||||||
gfile.P()
|
|
||||||
gfile.P(`micro_api "github.com/unistack-org/micro/v3/api"`)
|
|
||||||
gfile.P(`micro_client_http "github.com/unistack-org/micro-client-http/v3"`)
|
|
||||||
gfile.P(`micro_client "github.com/unistack-org/micro/v3/client"`)
|
|
||||||
gfile.P(`micro_server "github.com/unistack-org/micro/v3/server"`)
|
|
||||||
gfile.P(")")
|
|
||||||
gfile.P()
|
gfile.P()
|
||||||
|
|
||||||
gfile.P("// Reference imports to suppress errors if they are not otherwise used.")
|
gfile.Import(contextPackage)
|
||||||
gfile.P("var (")
|
gfile.Import(microApiPackage)
|
||||||
gfile.P("_ ", "micro_api.Endpoint")
|
gfile.Import(microClientPackage)
|
||||||
gfile.P("_ ", "context.Context")
|
gfile.Import(microClientHttpPackage)
|
||||||
gfile.P(" _ ", "micro_client.Option")
|
gfile.Import(microServerPackage)
|
||||||
gfile.P(" _ ", "micro_server.Option")
|
|
||||||
gfile.P(")")
|
|
||||||
gfile.P()
|
|
||||||
|
|
||||||
for _, service := range file.Services {
|
for _, service := range file.Services {
|
||||||
generateServiceClient(gfile, service)
|
generateServiceClient(gfile, service)
|
||||||
@@ -57,81 +37,8 @@ func (g *Generator) httpGenerate(component string, plugin *protogen.Plugin) erro
|
|||||||
generateServiceServer(gfile, service)
|
generateServiceServer(gfile, service)
|
||||||
generateServiceServerMethods(gfile, service)
|
generateServiceServerMethods(gfile, service)
|
||||||
generateServiceRegister(gfile, service)
|
generateServiceRegister(gfile, service)
|
||||||
if component == "http" {
|
|
||||||
for k, v := range getErrors(service) {
|
|
||||||
errors[k] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
files := make(map[string]*Error)
|
|
||||||
for _, file := range plugin.Files {
|
|
||||||
if !file.Generate {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
err, ok := files[file.GeneratedFilenamePrefix]
|
|
||||||
if !ok {
|
|
||||||
err = &Error{packageName: string(file.GoPackageName)}
|
|
||||||
}
|
|
||||||
fok := false
|
|
||||||
for _, message := range file.Messages {
|
|
||||||
if _, ok := errors["."+string(message.Desc.FullName())]; ok {
|
|
||||||
fok = true
|
|
||||||
err.types = append(err.types, string(message.Desc.FullName()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if fok {
|
|
||||||
files[file.GeneratedFilenamePrefix] = err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for file, err := range files {
|
|
||||||
gfile := plugin.NewGeneratedFile(file+"_micro_errors.pb.go", ".")
|
|
||||||
generateServiceErrors(gfile, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getErrors(service *protogen.Service) map[string]struct{} {
|
|
||||||
errors := make(map[string]struct{})
|
|
||||||
|
|
||||||
for _, method := range service.Methods {
|
|
||||||
if method.Desc.Options() == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if !proto.HasExtension(method.Desc.Options(), openapi_options.E_Openapiv2Operation) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
opts := proto.GetExtension(method.Desc.Options(), openapi_options.E_Openapiv2Operation)
|
|
||||||
if opts == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
r := opts.(*openapi_options.Operation)
|
|
||||||
for _, response := range r.Responses {
|
|
||||||
if response.Schema == nil || response.Schema.JsonSchema == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
errors[response.Schema.JsonSchema.Ref] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return errors
|
|
||||||
}
|
|
||||||
|
|
||||||
func generateServiceErrors(gfile *protogen.GeneratedFile, err *Error) {
|
|
||||||
gfile.P("package ", err.packageName)
|
|
||||||
gfile.P("import (")
|
|
||||||
gfile.P(`"fmt"`)
|
|
||||||
gfile.P(")")
|
|
||||||
for _, typ := range err.types {
|
|
||||||
gfile.P("func (err *", typ[strings.LastIndex(typ, ".")+1:], ") Error() string {")
|
|
||||||
gfile.P(`return fmt.Sprintf("%#v", err)`)
|
|
||||||
gfile.P("}")
|
|
||||||
gfile.P()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
26
main.go
26
main.go
@@ -9,23 +9,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
flags flag.FlagSet
|
flagDebug = flag.Bool("debug", false, "")
|
||||||
flagDebug *bool
|
flagStandalone = flag.Bool("standalone", false, "")
|
||||||
flagComponents *string
|
flagComponents = flag.String("components", "micro|rpc", "")
|
||||||
flagPaths *string
|
|
||||||
flagModule *string
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
|
||||||
flagDebug = flags.Bool("debug", false, "")
|
|
||||||
flagComponents = flags.String("components", "micro", "")
|
|
||||||
flagPaths = flag.String("paths", "", "")
|
|
||||||
flagModule = flag.String("module", "", "")
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
opts := &protogen.Options{
|
opts := &protogen.Options{
|
||||||
ParamFunc: flags.Set,
|
ParamFunc: flag.CommandLine.Set,
|
||||||
}
|
}
|
||||||
|
|
||||||
g := &Generator{}
|
g := &Generator{}
|
||||||
@@ -34,13 +25,20 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Generator struct {
|
type Generator struct {
|
||||||
|
components string
|
||||||
|
standalone bool
|
||||||
|
debug bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Generator) Generate(plugin *protogen.Plugin) error {
|
func (g *Generator) Generate(plugin *protogen.Plugin) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
g.standalone = *flagStandalone
|
||||||
|
g.debug = *flagDebug
|
||||||
|
g.components = *flagComponents
|
||||||
|
|
||||||
// Protoc passes a slice of File structs for us to process
|
// Protoc passes a slice of File structs for us to process
|
||||||
for _, component := range strings.Split(*flagComponents, "|") {
|
for _, component := range strings.Split(g.components, "|") {
|
||||||
switch component {
|
switch component {
|
||||||
case "micro":
|
case "micro":
|
||||||
err = g.microGenerate(component, plugin)
|
err = g.microGenerate(component, plugin)
|
||||||
|
25
micro.go
25
micro.go
@@ -14,28 +14,21 @@ func (g *Generator) microGenerate(component string, plugin *protogen.Plugin) err
|
|||||||
}
|
}
|
||||||
|
|
||||||
gname := file.GeneratedFilenamePrefix + "_" + component + ".pb.go"
|
gname := file.GeneratedFilenamePrefix + "_" + component + ".pb.go"
|
||||||
gfile := plugin.NewGeneratedFile(gname, ".")
|
|
||||||
|
path := file.GoImportPath
|
||||||
|
if g.standalone {
|
||||||
|
path = "."
|
||||||
|
}
|
||||||
|
gfile := plugin.NewGeneratedFile(gname, path)
|
||||||
|
|
||||||
gfile.P("// Code generated by protoc-gen-micro")
|
gfile.P("// Code generated by protoc-gen-micro")
|
||||||
gfile.P("// source: ", *file.Proto.Name)
|
gfile.P("// source: ", *file.Proto.Name)
|
||||||
gfile.P("package ", file.GoPackageName)
|
gfile.P("package ", file.GoPackageName)
|
||||||
|
|
||||||
gfile.P()
|
|
||||||
gfile.P("import (")
|
|
||||||
gfile.P(`"context"`)
|
|
||||||
gfile.P()
|
|
||||||
gfile.P(`micro_api "github.com/unistack-org/micro/v3/api"`)
|
|
||||||
gfile.P(`micro_client "github.com/unistack-org/micro/v3/client"`)
|
|
||||||
gfile.P(")")
|
|
||||||
gfile.P()
|
gfile.P()
|
||||||
|
|
||||||
gfile.P("// Reference imports to suppress errors if they are not otherwise used.")
|
gfile.Import(contextPackage)
|
||||||
gfile.P("var (")
|
gfile.Import(microApiPackage)
|
||||||
gfile.P("_ ", "micro_api.Endpoint")
|
gfile.Import(microClientPackage)
|
||||||
gfile.P("_ ", "context.Context")
|
|
||||||
gfile.P(" _ ", "micro_client.Option")
|
|
||||||
gfile.P(")")
|
|
||||||
gfile.P()
|
|
||||||
|
|
||||||
// generate services
|
// generate services
|
||||||
for _, service := range file.Services {
|
for _, service := range file.Services {
|
||||||
|
27
rpc.go
27
rpc.go
@@ -14,30 +14,21 @@ func (g *Generator) rpcGenerate(component string, plugin *protogen.Plugin) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
gname := file.GeneratedFilenamePrefix + "_micro_" + component + ".pb.go"
|
gname := file.GeneratedFilenamePrefix + "_micro_" + component + ".pb.go"
|
||||||
gfile := plugin.NewGeneratedFile(gname, ".")
|
path := file.GoImportPath
|
||||||
|
if g.standalone {
|
||||||
|
path = "."
|
||||||
|
}
|
||||||
|
gfile := plugin.NewGeneratedFile(gname, path)
|
||||||
|
|
||||||
gfile.P("// Code generated by protoc-gen-micro")
|
gfile.P("// Code generated by protoc-gen-micro")
|
||||||
gfile.P("// source: ", *file.Proto.Name)
|
gfile.P("// source: ", *file.Proto.Name)
|
||||||
gfile.P("package ", file.GoPackageName)
|
gfile.P("package ", file.GoPackageName)
|
||||||
|
|
||||||
gfile.P()
|
|
||||||
gfile.P("import (")
|
|
||||||
gfile.P(`"context"`)
|
|
||||||
gfile.P()
|
|
||||||
gfile.P(`micro_api "github.com/unistack-org/micro/v3/api"`)
|
|
||||||
gfile.P(`micro_client "github.com/unistack-org/micro/v3/client"`)
|
|
||||||
gfile.P(`micro_server "github.com/unistack-org/micro/v3/server"`)
|
|
||||||
gfile.P(")")
|
|
||||||
gfile.P()
|
gfile.P()
|
||||||
|
|
||||||
gfile.P("// Reference imports to suppress errors if they are not otherwise used.")
|
gfile.Import(contextPackage)
|
||||||
gfile.P("var (")
|
gfile.Import(microApiPackage)
|
||||||
gfile.P("_ ", "micro_api.Endpoint")
|
gfile.Import(microClientPackage)
|
||||||
gfile.P("_ ", "context.Context")
|
gfile.Import(microServerPackage)
|
||||||
gfile.P(" _ ", "micro_client.Option")
|
|
||||||
gfile.P(" _ ", "micro_server.Option")
|
|
||||||
gfile.P(")")
|
|
||||||
gfile.P()
|
|
||||||
|
|
||||||
for _, service := range file.Services {
|
for _, service := range file.Services {
|
||||||
generateServiceClient(gfile, service)
|
generateServiceClient(gfile, service)
|
||||||
|
312
util.go
312
util.go
@@ -10,29 +10,44 @@ import (
|
|||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
func lowerFirst(s string) string {
|
var (
|
||||||
|
reflectPackage = protogen.GoImportPath("reflect")
|
||||||
|
stringsPackage = protogen.GoImportPath("strings")
|
||||||
|
fmtPackage = protogen.GoImportPath("fmt")
|
||||||
|
contextPackage = protogen.GoImportPath("context")
|
||||||
|
httpPackage = protogen.GoImportPath("net/http")
|
||||||
|
gorillaMuxPackage = protogen.GoImportPath("github.com/gorilla/mux")
|
||||||
|
chiPackage = protogen.GoImportPath("github.com/go-chi/chi/v4")
|
||||||
|
chiMiddlewarePackage = protogen.GoImportPath("github.com/go-chi/chi/v4/middleware")
|
||||||
|
microApiPackage = protogen.GoImportPath("github.com/unistack-org/micro/v3/api")
|
||||||
|
microClientPackage = protogen.GoImportPath("github.com/unistack-org/micro/v3/client")
|
||||||
|
microServerPackage = protogen.GoImportPath("github.com/unistack-org/micro/v3/server")
|
||||||
|
microClientHttpPackage = protogen.GoImportPath("github.com/unistack-org/micro-client-http/v3")
|
||||||
|
deprecationComment = "// Deprecated: Do not use."
|
||||||
|
)
|
||||||
|
|
||||||
|
func unexport(s string) string {
|
||||||
return strings.ToLower(s[:1]) + s[1:]
|
return strings.ToLower(s[:1]) + s[1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateServiceClient(gfile *protogen.GeneratedFile, service *protogen.Service) {
|
func generateServiceClient(gfile *protogen.GeneratedFile, service *protogen.Service) {
|
||||||
serviceName := strings.TrimSuffix(service.GoName, "Service")
|
serviceName := service.GoName
|
||||||
gfile.P("type ", lowerFirst(serviceName), "Service struct {")
|
gfile.P("type ", unexport(serviceName), "Client struct {")
|
||||||
gfile.P("c micro_client.Client")
|
gfile.P("c ", microClientPackage.Ident("Client"))
|
||||||
gfile.P("name string")
|
gfile.P("name string")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
|
|
||||||
gfile.P("// New", serviceName, "Service create new service client")
|
gfile.P("func New", serviceName, "Client(name string, c ", microClientPackage.Ident("Client"), ") ", serviceName, "Client {")
|
||||||
gfile.P("func New", serviceName, "Service(name string, c micro_client.Client) ", serviceName, "Service {")
|
gfile.P("return &", unexport(serviceName), "Client{c: c, name: name}")
|
||||||
gfile.P("return &", lowerFirst(serviceName), "Service{c: c, name: name}")
|
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P()
|
gfile.P()
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateServiceClientMethods(gfile *protogen.GeneratedFile, service *protogen.Service, http bool) {
|
func generateServiceClientMethods(gfile *protogen.GeneratedFile, service *protogen.Service, http bool) {
|
||||||
serviceName := strings.TrimSuffix(service.GoName, "Service")
|
serviceName := service.GoName
|
||||||
for _, method := range service.Methods {
|
for _, method := range service.Methods {
|
||||||
methodName := fmt.Sprintf("%s.%s", serviceName, method.GoName)
|
methodName := fmt.Sprintf("%s.%s", serviceName, method.GoName)
|
||||||
gfile.P("func (c *", lowerFirst(serviceName), "Service) ", generateClientSignature(serviceName, method), "{")
|
generateClientFuncSignature(gfile, serviceName, method)
|
||||||
|
|
||||||
if http && method.Desc.Options() != nil {
|
if http && method.Desc.Options() != nil {
|
||||||
if proto.HasExtension(method.Desc.Options(), openapi_options.E_Openapiv2Operation) {
|
if proto.HasExtension(method.Desc.Options(), openapi_options.E_Openapiv2Operation) {
|
||||||
@@ -41,26 +56,25 @@ func generateServiceClientMethods(gfile *protogen.GeneratedFile, service *protog
|
|||||||
r := opts.(*openapi_options.Operation)
|
r := opts.(*openapi_options.Operation)
|
||||||
gfile.P("errmap := make(map[string]interface{}, ", len(r.Responses), ")")
|
gfile.P("errmap := make(map[string]interface{}, ", len(r.Responses), ")")
|
||||||
for code, response := range r.Responses {
|
for code, response := range r.Responses {
|
||||||
if response.Schema == nil || response.Schema.JsonSchema == nil {
|
if response.Schema != nil && response.Schema.JsonSchema != nil {
|
||||||
continue
|
ref := response.Schema.JsonSchema.Ref
|
||||||
|
if strings.HasPrefix(ref, "."+string(service.Desc.ParentFile().Package())+".") {
|
||||||
|
ref = strings.TrimPrefix(ref, "."+string(service.Desc.ParentFile().Package())+".")
|
||||||
|
}
|
||||||
|
gfile.P(`errmap["`, code, `"] = &`, ref, "{}")
|
||||||
}
|
}
|
||||||
ref := response.Schema.JsonSchema.Ref
|
|
||||||
if strings.HasPrefix(ref, "."+string(service.Desc.ParentFile().Package())+".") {
|
|
||||||
ref = strings.TrimPrefix(ref, "."+string(service.Desc.ParentFile().Package())+".")
|
|
||||||
}
|
|
||||||
gfile.P(`errmap["`, code, `"] = &`, ref, "{}")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gfile.P("opts = append(opts,")
|
gfile.P("opts = append(opts,")
|
||||||
gfile.P("micro_client_http.ErrorMap(errmap),")
|
gfile.P(microClientHttpPackage.Ident("ErrorMap"), "(errmap),")
|
||||||
|
|
||||||
if proto.HasExtension(method.Desc.Options(), api_options.E_Http) {
|
if proto.HasExtension(method.Desc.Options(), api_options.E_Http) {
|
||||||
endpoints, _ := generateEndpoints(method)
|
endpoints, _ := generateEndpoints(method)
|
||||||
path, method, body := getEndpoint(endpoints[0])
|
path, method, body := getEndpoint(endpoints[0])
|
||||||
gfile.P(`micro_client_http.Method("`, method, `"),`)
|
gfile.P(microClientHttpPackage.Ident("Method"), `("`, method, `"),`)
|
||||||
gfile.P(`micro_client_http.Path("`, path, `"),`)
|
gfile.P(microClientHttpPackage.Ident("Path"), `("`, path, `"),`)
|
||||||
gfile.P(`micro_client_http.Body("`, body, `"),`)
|
gfile.P(microClientHttpPackage.Ident("Body"), `("`, body, `"),`)
|
||||||
}
|
}
|
||||||
|
|
||||||
gfile.P(")")
|
gfile.P(")")
|
||||||
@@ -68,7 +82,7 @@ func generateServiceClientMethods(gfile *protogen.GeneratedFile, service *protog
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !method.Desc.IsStreamingServer() && !method.Desc.IsStreamingClient() {
|
if !method.Desc.IsStreamingServer() && !method.Desc.IsStreamingClient() {
|
||||||
gfile.P("rsp := &", method.Output.Desc.Name(), "{}")
|
gfile.P("rsp := &", gfile.QualifiedGoIdent(method.Output.GoIdent), "{}")
|
||||||
gfile.P(`err := c.c.Call(ctx, c.c.NewRequest(c.name, "`, methodName, `", req), rsp, opts...)`)
|
gfile.P(`err := c.c.Call(ctx, c.c.NewRequest(c.name, "`, methodName, `", req), rsp, opts...)`)
|
||||||
gfile.P("if err != nil {")
|
gfile.P("if err != nil {")
|
||||||
gfile.P("return nil, err")
|
gfile.P("return nil, err")
|
||||||
@@ -76,10 +90,10 @@ func generateServiceClientMethods(gfile *protogen.GeneratedFile, service *protog
|
|||||||
gfile.P("return rsp, nil")
|
gfile.P("return rsp, nil")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P()
|
gfile.P()
|
||||||
return
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
gfile.P(`stream, err := c.c.Stream(ctx, c.c.NewRequest(c.name, "`, methodName, `", &`, method.Input.Desc.Name(), `{}), opts...)`)
|
gfile.P(`stream, err := c.c.Stream(ctx, c.c.NewRequest(c.name, "`, methodName, `", &`, gfile.QualifiedGoIdent(method.Input.GoIdent), `{}), opts...)`)
|
||||||
gfile.P("if err != nil {")
|
gfile.P("if err != nil {")
|
||||||
gfile.P("return nil, err")
|
gfile.P("return nil, err")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
@@ -89,62 +103,62 @@ func generateServiceClientMethods(gfile *protogen.GeneratedFile, service *protog
|
|||||||
gfile.P("return nil, err")
|
gfile.P("return nil, err")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
}
|
}
|
||||||
gfile.P("return &", lowerFirst(serviceName), "Service", method.GoName, "{stream}, nil")
|
gfile.P("return &", unexport(serviceName), "Client", method.GoName, "{stream}, nil")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P()
|
gfile.P()
|
||||||
|
|
||||||
if method.Desc.IsStreamingServer() || method.Desc.IsStreamingClient() {
|
if method.Desc.IsStreamingServer() || method.Desc.IsStreamingClient() {
|
||||||
gfile.P("type ", lowerFirst(serviceName), "Service", method.GoName, " struct {")
|
gfile.P("type ", unexport(serviceName), "Client", method.GoName, " struct {")
|
||||||
gfile.P("stream micro_client.Stream")
|
gfile.P("stream ", microClientPackage.Ident("Stream"))
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
}
|
}
|
||||||
|
|
||||||
if method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() {
|
if method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() {
|
||||||
gfile.P("func (s *", lowerFirst(serviceName), "Service", method.GoName, ") RecvAndClose() (*", method.Output.Desc.Name(), ", error) {")
|
gfile.P("func (s *", unexport(serviceName), "Client", method.GoName, ") RecvAndClose() (*", gfile.QualifiedGoIdent(method.Output.GoIdent), ", error) {")
|
||||||
gfile.P("m := &", method.Output.Desc.Name(), "{}")
|
gfile.P("msg := &", gfile.QualifiedGoIdent(method.Output.GoIdent), "{}")
|
||||||
gfile.P("err := s.RecvMsg(m)")
|
gfile.P("err := s.RecvMsg(msg)")
|
||||||
gfile.P("if err == nil {")
|
gfile.P("if err == nil {")
|
||||||
gfile.P("err = s.Close()")
|
gfile.P("err = s.Close()")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P("if err != nil {")
|
gfile.P("if err != nil {")
|
||||||
gfile.P("return nil, err")
|
gfile.P("return nil, err")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P("return m, nil")
|
gfile.P("return msg, nil")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
}
|
}
|
||||||
|
|
||||||
gfile.P()
|
gfile.P()
|
||||||
gfile.P("func (s *", lowerFirst(serviceName), "Service", method.GoName, ") Close() error {")
|
gfile.P("func (s *", unexport(serviceName), "Client", method.GoName, ") Close() error {")
|
||||||
gfile.P("return s.stream.Close()")
|
gfile.P("return s.stream.Close()")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P()
|
gfile.P()
|
||||||
gfile.P("func (s *", lowerFirst(serviceName), "Service", method.GoName, ") Context() context.Context {")
|
gfile.P("func (s *", unexport(serviceName), "Client", method.GoName, ") Context() ", contextPackage.Ident("Context"), " {")
|
||||||
gfile.P("return s.stream.Context()")
|
gfile.P("return s.stream.Context()")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P()
|
gfile.P()
|
||||||
gfile.P("func (s *", lowerFirst(serviceName), "Service", method.GoName, ") SendMsg(m interface{}) error {")
|
gfile.P("func (s *", unexport(serviceName), "Client", method.GoName, ") SendMsg(msg interface{}) error {")
|
||||||
gfile.P("return s.stream.Send(m)")
|
gfile.P("return s.stream.Send(msg)")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P()
|
gfile.P()
|
||||||
gfile.P("func (s *", lowerFirst(serviceName), "Service", method.GoName, ") RecvMsg(m interface{}) error {")
|
gfile.P("func (s *", unexport(serviceName), "Client", method.GoName, ") RecvMsg(msg interface{}) error {")
|
||||||
gfile.P("return s.stream.Recv(m)")
|
gfile.P("return s.stream.Recv(msg)")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P()
|
gfile.P()
|
||||||
|
|
||||||
if method.Desc.IsStreamingClient() {
|
if method.Desc.IsStreamingClient() {
|
||||||
gfile.P("func (s *", lowerFirst(serviceName), "Service", method.GoName, ") Send(m *", method.Input.Desc.Name(), ") error {")
|
gfile.P("func (s *", unexport(serviceName), "Client", method.GoName, ") Send(msg *", gfile.QualifiedGoIdent(method.Input.GoIdent), ") error {")
|
||||||
gfile.P("return s.stream.Send(m)")
|
gfile.P("return s.stream.Send(msg)")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P()
|
gfile.P()
|
||||||
}
|
}
|
||||||
|
|
||||||
if method.Desc.IsStreamingServer() {
|
if method.Desc.IsStreamingServer() {
|
||||||
gfile.P("func (s *", lowerFirst(serviceName), "Service", method.GoName, ") Recv() (*", method.Output.Desc.Name(), ", error) {")
|
gfile.P("func (s *", unexport(serviceName), "Client", method.GoName, ") Recv() (*", gfile.QualifiedGoIdent(method.Output.GoIdent), ", error) {")
|
||||||
gfile.P("m := &", method.Output.Desc.Name(), "{}")
|
gfile.P("msg := &", gfile.QualifiedGoIdent(method.Output.GoIdent), "{}")
|
||||||
gfile.P("if err := s.stream.Recv(m); err != nil {")
|
gfile.P("if err := s.stream.Recv(msg); err != nil {")
|
||||||
gfile.P("return nil, err")
|
gfile.P("return nil, err")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P("return m, nil")
|
gfile.P("return msg, nil")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P()
|
gfile.P()
|
||||||
}
|
}
|
||||||
@@ -152,45 +166,43 @@ func generateServiceClientMethods(gfile *protogen.GeneratedFile, service *protog
|
|||||||
}
|
}
|
||||||
|
|
||||||
func generateServiceServer(gfile *protogen.GeneratedFile, service *protogen.Service) {
|
func generateServiceServer(gfile *protogen.GeneratedFile, service *protogen.Service) {
|
||||||
serviceName := strings.TrimSuffix(service.GoName, "Service")
|
serviceName := service.GoName
|
||||||
gfile.P("type ", lowerFirst(serviceName), "Handler struct {")
|
gfile.P("type ", unexport(serviceName), "Server struct {")
|
||||||
gfile.P(serviceName, "Handler")
|
gfile.P(serviceName, "Server")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P()
|
gfile.P()
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateServiceServerMethods(gfile *protogen.GeneratedFile, service *protogen.Service) {
|
func generateServiceServerMethods(gfile *protogen.GeneratedFile, service *protogen.Service) {
|
||||||
serviceName := strings.TrimSuffix(service.GoName, "Service")
|
serviceName := service.GoName
|
||||||
for _, method := range service.Methods {
|
for _, method := range service.Methods {
|
||||||
//methodName := fmt.Sprintf("%s.%s", serviceName, method.GoName)
|
generateServerFuncSignature(gfile, serviceName, method, true)
|
||||||
gfile.P("func (h *", lowerFirst(serviceName), "Handler) ", generateServerSignature(serviceName, method), "{")
|
|
||||||
generateServerSignature(serviceName, method)
|
|
||||||
|
|
||||||
if method.Desc.IsStreamingClient() || method.Desc.IsStreamingServer() {
|
if method.Desc.IsStreamingClient() || method.Desc.IsStreamingServer() {
|
||||||
if !method.Desc.IsStreamingClient() {
|
if !method.Desc.IsStreamingClient() {
|
||||||
gfile.P("m := &", method.Input.Desc.Name(), "{}")
|
gfile.P("msg := &", gfile.QualifiedGoIdent(method.Input.GoIdent), "{}")
|
||||||
gfile.P("if err := stream.Recv(m); err != nil {")
|
gfile.P("if err := stream.Recv(msg); err != nil {")
|
||||||
gfile.P("return err")
|
gfile.P("return err")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P("return h.", serviceName, "Handler.", method.GoName, "(ctx, m, &", lowerFirst(serviceName), method.GoName, ",Stream{stream})")
|
gfile.P("return h.", serviceName, "Server.", method.GoName, "(ctx, msg, &", unexport(serviceName), method.GoName, "Stream{stream})")
|
||||||
} else {
|
} else {
|
||||||
gfile.P("return h.", serviceName, "Handler.", method.GoName, "(ctx, &", lowerFirst(serviceName), method.GoName, "Stream{stream})")
|
gfile.P("return h.", serviceName, "Server.", method.GoName, "(ctx, &", unexport(serviceName), method.GoName, "Stream{stream})")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gfile.P("return h.", serviceName, "Handler.", method.GoName, "(ctx, req, rsp)")
|
gfile.P("return h.", serviceName, "Server.", method.GoName, "(ctx, req, rsp)")
|
||||||
}
|
}
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P()
|
gfile.P()
|
||||||
|
|
||||||
if method.Desc.IsStreamingClient() || method.Desc.IsStreamingServer() {
|
if method.Desc.IsStreamingClient() || method.Desc.IsStreamingServer() {
|
||||||
gfile.P("type ", lowerFirst(serviceName), method.GoName, "Stream struct {")
|
gfile.P("type ", unexport(serviceName), method.GoName, "Stream struct {")
|
||||||
gfile.P("stream micro_server.Stream")
|
gfile.P("stream ", microServerPackage.Ident("Stream"))
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
}
|
}
|
||||||
|
|
||||||
if method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() {
|
if method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() {
|
||||||
gfile.P("func (s *", lowerFirst(serviceName), method.GoName, "Stream) SendAndClose(m *", method.Output.Desc.Name(), ") error {")
|
gfile.P("func (s *", unexport(serviceName), method.GoName, "Stream) SendAndClose(msg *", gfile.QualifiedGoIdent(method.Output.GoIdent), ") error {")
|
||||||
gfile.P("err := s.SendMsg(m)")
|
gfile.P("err := s.SendMsg(msg)")
|
||||||
gfile.P("if err == nil {")
|
gfile.P("if err == nil {")
|
||||||
gfile.P("err = s.stream.Close()")
|
gfile.P("err = s.stream.Close()")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
@@ -199,40 +211,40 @@ func generateServiceServerMethods(gfile *protogen.GeneratedFile, service *protog
|
|||||||
}
|
}
|
||||||
|
|
||||||
if method.Desc.IsStreamingClient() || method.Desc.IsStreamingServer() {
|
if method.Desc.IsStreamingClient() || method.Desc.IsStreamingServer() {
|
||||||
gfile.P("func (s *", lowerFirst(serviceName), method.GoName, "Stream) Close() error {")
|
gfile.P("func (s *", unexport(serviceName), method.GoName, "Stream) Close() error {")
|
||||||
gfile.P("return s.stream.Close()")
|
gfile.P("return s.stream.Close()")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P()
|
gfile.P()
|
||||||
|
|
||||||
gfile.P("func (s *", lowerFirst(serviceName), method.GoName, "Stream) Context() context.Context {")
|
gfile.P("func (s *", unexport(serviceName), method.GoName, "Stream) Context() ", contextPackage.Ident("Context"), " {")
|
||||||
gfile.P("return s.stream.Context()")
|
gfile.P("return s.stream.Context()")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P()
|
gfile.P()
|
||||||
|
|
||||||
gfile.P("func (s *", lowerFirst(serviceName), method.GoName, "Stream) SendMsg(m interface{}) error {")
|
gfile.P("func (s *", unexport(serviceName), method.GoName, "Stream) SendMsg(msg interface{}) error {")
|
||||||
gfile.P("return s.stream.Send(m)")
|
gfile.P("return s.stream.Send(msg)")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P()
|
gfile.P()
|
||||||
|
|
||||||
gfile.P("func (s *", lowerFirst(serviceName), method.GoName, "Stream) RecvMsg(m interface{}) error {")
|
gfile.P("func (s *", unexport(serviceName), method.GoName, "Stream) RecvMsg(msg interface{}) error {")
|
||||||
gfile.P("return s.stream.Recv(m)")
|
gfile.P("return s.stream.Recv(msg)")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P()
|
gfile.P()
|
||||||
|
|
||||||
if method.Desc.IsStreamingServer() {
|
if method.Desc.IsStreamingServer() {
|
||||||
gfile.P("func (s *", lowerFirst(serviceName), method.GoName, "Stream) Send(m *", method.Output.Desc.Name(), ") error {")
|
gfile.P("func (s *", unexport(serviceName), method.GoName, "Stream) Send(msg *", gfile.QualifiedGoIdent(method.Output.GoIdent), ") error {")
|
||||||
gfile.P("return s.stream.Send(m)")
|
gfile.P("return s.stream.Send(msg)")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P()
|
gfile.P()
|
||||||
}
|
}
|
||||||
|
|
||||||
if method.Desc.IsStreamingClient() {
|
if method.Desc.IsStreamingClient() {
|
||||||
gfile.P("func (s *", lowerFirst(serviceName), method.GoName, "Stream) Recv() (*", method.Input.Desc.Name(), ", error) {")
|
gfile.P("func (s *", unexport(serviceName), method.GoName, "Stream) Recv() (*", gfile.QualifiedGoIdent(method.Input.GoIdent), ", error) {")
|
||||||
gfile.P("m := &", method.Input.Desc.Name(), "{}")
|
gfile.P("msg := &", gfile.QualifiedGoIdent(method.Input.GoIdent), "{}")
|
||||||
gfile.P("if err := s.stream.Recv(m); err != nil {")
|
gfile.P("if err := s.stream.Recv(msg); err != nil {")
|
||||||
gfile.P("return nil, err")
|
gfile.P("return nil, err")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P("return m, nil")
|
gfile.P("return msg, nil")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P()
|
gfile.P()
|
||||||
}
|
}
|
||||||
@@ -242,127 +254,183 @@ func generateServiceServerMethods(gfile *protogen.GeneratedFile, service *protog
|
|||||||
}
|
}
|
||||||
|
|
||||||
func generateServiceRegister(gfile *protogen.GeneratedFile, service *protogen.Service) {
|
func generateServiceRegister(gfile *protogen.GeneratedFile, service *protogen.Service) {
|
||||||
serviceName := strings.TrimSuffix(service.GoName, "Service")
|
serviceName := service.GoName
|
||||||
gfile.P("func Register", serviceName, "Handler(s micro_server.Server, sh ", serviceName, "Handler, opts ...micro_server.HandlerOption) error {")
|
gfile.P("func Register", serviceName, "Server(s ", microServerPackage.Ident("Server"), ", sh ", serviceName, "Server, opts ...", microServerPackage.Ident("HandlerOption"), ") error {")
|
||||||
gfile.P("type ", lowerFirst(serviceName), " interface {")
|
gfile.P("type ", unexport(serviceName), " interface {")
|
||||||
for _, method := range service.Methods {
|
for _, method := range service.Methods {
|
||||||
gfile.P(generateServerSignature(serviceName, method))
|
generateServerSignature(gfile, serviceName, method, true)
|
||||||
}
|
}
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P("type ", serviceName, " struct {")
|
gfile.P("type ", serviceName, " struct {")
|
||||||
gfile.P(lowerFirst(serviceName))
|
gfile.P(unexport(serviceName))
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P("h := &", lowerFirst(serviceName), "Handler{sh}")
|
gfile.P("h := &", unexport(serviceName), "Server{sh}")
|
||||||
gfile.P("for _, endpoint := range New", serviceName, "Endpoints() {")
|
gfile.P("for _, endpoint := range New", serviceName, "Endpoints() {")
|
||||||
gfile.P("opts = append(opts, micro_api.WithEndpoint(endpoint))")
|
gfile.P("opts = append(opts, ", microApiPackage.Ident("WithEndpoint"), "(endpoint))")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P("return s.Handle(s.NewHandler(&", serviceName, "{h}, opts...))")
|
gfile.P("return s.Handle(s.NewHandler(&", serviceName, "{h}, opts...))")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateServerSignature(serviceName string, method *protogen.Method) string {
|
func generateServerFuncSignature(gfile *protogen.GeneratedFile, serviceName string, method *protogen.Method, private bool) {
|
||||||
methodName := string(method.GoName)
|
args := append([]interface{}{},
|
||||||
req := []string{"ctx context.Context"}
|
"func (h *", unexport(serviceName), "Server) ", method.GoName,
|
||||||
ret := "error"
|
"(ctx ", contextPackage.Ident("Context"),
|
||||||
|
)
|
||||||
if !method.Desc.IsStreamingClient() {
|
if private && (method.Desc.IsStreamingClient() || method.Desc.IsStreamingServer()) {
|
||||||
req = append(req, "req *"+string(method.Input.Desc.Name()))
|
args = append(args, ", stream ", microServerPackage.Ident("Stream"))
|
||||||
|
} else {
|
||||||
|
if !method.Desc.IsStreamingClient() {
|
||||||
|
args = append(args, ", req *", gfile.QualifiedGoIdent(method.Input.GoIdent))
|
||||||
|
}
|
||||||
|
if method.Desc.IsStreamingServer() || method.Desc.IsStreamingClient() {
|
||||||
|
args = append(args, ", stream ", serviceName, "_", method.GoName, "Stream")
|
||||||
|
}
|
||||||
|
if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() {
|
||||||
|
args = append(args, ", rsp *", gfile.QualifiedGoIdent(method.Output.GoIdent))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if method.Desc.IsStreamingServer() || method.Desc.IsStreamingClient() {
|
args = append(args, ") error {")
|
||||||
req = append(req, "stream "+serviceName+"_"+methodName+"Stream")
|
gfile.P(args...)
|
||||||
}
|
|
||||||
if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() {
|
|
||||||
req = append(req, "rsp *"+string(method.Output.Desc.Name()))
|
|
||||||
}
|
|
||||||
return methodName + "(" + strings.Join(req, ", ") + ") " + ret
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateClientSignature(serviceName string, method *protogen.Method) string {
|
func generateServerSignature(gfile *protogen.GeneratedFile, serviceName string, method *protogen.Method, private bool) {
|
||||||
methodName := string(method.GoName)
|
args := append([]interface{}{},
|
||||||
req := ", req *" + string(method.Input.Desc.Name())
|
method.GoName,
|
||||||
if method.Desc.IsStreamingClient() {
|
"(ctx ", contextPackage.Ident("Context"),
|
||||||
req = ""
|
)
|
||||||
|
if private && (method.Desc.IsStreamingClient() || method.Desc.IsStreamingServer()) {
|
||||||
|
args = append(args, ", stream ", microServerPackage.Ident("Stream"))
|
||||||
|
} else {
|
||||||
|
if !method.Desc.IsStreamingClient() {
|
||||||
|
args = append(args, ", req *", gfile.QualifiedGoIdent(method.Input.GoIdent))
|
||||||
|
}
|
||||||
|
if method.Desc.IsStreamingServer() || method.Desc.IsStreamingClient() {
|
||||||
|
args = append(args, ", stream ", serviceName, "_", method.GoName, "Stream")
|
||||||
|
}
|
||||||
|
if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() {
|
||||||
|
args = append(args, ", rsp *", gfile.QualifiedGoIdent(method.Output.GoIdent))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rsp := "*" + string(method.Output.Desc.Name())
|
args = append(args, ") error")
|
||||||
if method.Desc.IsStreamingClient() || method.Desc.IsStreamingServer() {
|
gfile.P(args...)
|
||||||
rsp = serviceName + "_" + methodName + "Service"
|
}
|
||||||
|
|
||||||
|
func generateClientFuncSignature(gfile *protogen.GeneratedFile, serviceName string, method *protogen.Method) {
|
||||||
|
args := append([]interface{}{},
|
||||||
|
"func (c *",
|
||||||
|
unexport(serviceName),
|
||||||
|
"Client) ",
|
||||||
|
method.GoName,
|
||||||
|
"(ctx ", contextPackage.Ident("Context"), ", ",
|
||||||
|
)
|
||||||
|
if !method.Desc.IsStreamingClient() {
|
||||||
|
args = append(args, "req *", gfile.QualifiedGoIdent(method.Input.GoIdent), ", ")
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%s(ctx context.Context%s, opts ...micro_client.CallOption) (%s, error)", methodName, req, rsp)
|
args = append(args, "opts ...", microClientPackage.Ident("CallOption"), ") (")
|
||||||
|
if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() {
|
||||||
|
args = append(args, "*", gfile.QualifiedGoIdent(method.Output.GoIdent))
|
||||||
|
} else {
|
||||||
|
args = append(args, serviceName, "_", method.GoName, "Client")
|
||||||
|
}
|
||||||
|
args = append(args, ", error) {")
|
||||||
|
gfile.P(args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateClientSignature(gfile *protogen.GeneratedFile, serviceName string, method *protogen.Method) {
|
||||||
|
args := append([]interface{}{},
|
||||||
|
method.GoName,
|
||||||
|
"(ctx ", contextPackage.Ident("Context"), ", ",
|
||||||
|
)
|
||||||
|
if !method.Desc.IsStreamingClient() {
|
||||||
|
args = append(args, "req *", gfile.QualifiedGoIdent(method.Input.GoIdent), ", ")
|
||||||
|
}
|
||||||
|
args = append(args, "opts ...", microClientPackage.Ident("CallOption"), ") (")
|
||||||
|
if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() {
|
||||||
|
args = append(args, "*", gfile.QualifiedGoIdent(method.Output.GoIdent))
|
||||||
|
} else {
|
||||||
|
args = append(args, serviceName, "_", method.GoName, "Client")
|
||||||
|
}
|
||||||
|
args = append(args, ", error)")
|
||||||
|
gfile.P(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateServiceClientInterface(gfile *protogen.GeneratedFile, service *protogen.Service) {
|
func generateServiceClientInterface(gfile *protogen.GeneratedFile, service *protogen.Service) {
|
||||||
serviceName := strings.TrimSuffix(service.GoName, "Service")
|
serviceName := service.GoName
|
||||||
gfile.P("type ", serviceName, "Service interface {")
|
gfile.P("type ", serviceName, "Client interface {")
|
||||||
for _, method := range service.Methods {
|
for _, method := range service.Methods {
|
||||||
gfile.P(generateClientSignature(serviceName, method))
|
generateClientSignature(gfile, serviceName, method)
|
||||||
}
|
}
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P()
|
gfile.P()
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateServiceServerInterface(gfile *protogen.GeneratedFile, service *protogen.Service) {
|
func generateServiceServerInterface(gfile *protogen.GeneratedFile, service *protogen.Service) {
|
||||||
serviceName := strings.TrimSuffix(service.GoName, "Service")
|
serviceName := service.GoName
|
||||||
gfile.P("type ", serviceName, "Handler interface {")
|
gfile.P("type ", serviceName, "Server interface {")
|
||||||
for _, method := range service.Methods {
|
for _, method := range service.Methods {
|
||||||
gfile.P(generateServerSignature(serviceName, method))
|
generateServerSignature(gfile, serviceName, method, false)
|
||||||
}
|
}
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P()
|
gfile.P()
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateServiceClientStreamInterface(gfile *protogen.GeneratedFile, service *protogen.Service) {
|
func generateServiceClientStreamInterface(gfile *protogen.GeneratedFile, service *protogen.Service) {
|
||||||
serviceName := strings.TrimSuffix(service.GoName, "Service")
|
serviceName := service.GoName
|
||||||
for _, method := range service.Methods {
|
for _, method := range service.Methods {
|
||||||
if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() {
|
if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
methodName := method.GoName
|
methodName := method.GoName
|
||||||
gfile.P("type ", serviceName, "_", methodName, "Service interface {")
|
gfile.P("type ", serviceName, "_", methodName, "Client interface {")
|
||||||
gfile.P("Context() context.Context")
|
gfile.P("Context() ", contextPackage.Ident("Context"))
|
||||||
gfile.P("SendMsg(msg interface{}) error")
|
gfile.P("SendMsg(msg interface{}) error")
|
||||||
gfile.P("RecvMsg(msg interface{}) error")
|
gfile.P("RecvMsg(msg interface{}) error")
|
||||||
if method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() {
|
if method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() {
|
||||||
gfile.P("RecvAndClose() (", method.Output.Desc.Name(), ", error)")
|
gfile.P("RecvAndClose() (*", gfile.QualifiedGoIdent(method.Output.GoIdent), ", error)")
|
||||||
}
|
}
|
||||||
gfile.P("Close() error")
|
gfile.P("Close() error")
|
||||||
if method.Desc.IsStreamingClient() {
|
if method.Desc.IsStreamingClient() {
|
||||||
gfile.P("Send(msg *", method.Input.Desc.Name(), ") error")
|
gfile.P("Send(msg *", gfile.QualifiedGoIdent(method.Input.GoIdent), ") error")
|
||||||
}
|
}
|
||||||
if method.Desc.IsStreamingServer() {
|
if method.Desc.IsStreamingServer() {
|
||||||
gfile.P("Recv() (msg *", method.Output.Desc.Name(), ", error)")
|
gfile.P("Recv() (*", gfile.QualifiedGoIdent(method.Output.GoIdent), ", error)")
|
||||||
}
|
}
|
||||||
|
gfile.P("}")
|
||||||
|
gfile.P()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateServiceServerStreamInterface(gfile *protogen.GeneratedFile, service *protogen.Service) {
|
func generateServiceServerStreamInterface(gfile *protogen.GeneratedFile, service *protogen.Service) {
|
||||||
serviceName := strings.TrimSuffix(service.GoName, "Service")
|
serviceName := service.GoName
|
||||||
for _, method := range service.Methods {
|
for _, method := range service.Methods {
|
||||||
if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() {
|
if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
methodName := method.GoName
|
methodName := method.GoName
|
||||||
gfile.P("type ", serviceName, "_", methodName, "Stream interface {")
|
gfile.P("type ", serviceName, "_", methodName, "Stream interface {")
|
||||||
gfile.P("Context() context.Context")
|
gfile.P("Context() ", contextPackage.Ident("Context"))
|
||||||
gfile.P("SendMsg(msg interface{}) error")
|
gfile.P("SendMsg(msg interface{}) error")
|
||||||
gfile.P("RecvMsg(msg interface{}) error")
|
gfile.P("RecvMsg(msg interface{}) error")
|
||||||
if method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() {
|
if method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() {
|
||||||
gfile.P("SendAndClose(msg *", method.Output.Desc.Name(), ") error")
|
gfile.P("SendAndClose(msg *", gfile.QualifiedGoIdent(method.Output.GoIdent), ") error")
|
||||||
}
|
}
|
||||||
gfile.P("Close() error")
|
gfile.P("Close() error")
|
||||||
if method.Desc.IsStreamingClient() {
|
if method.Desc.IsStreamingClient() {
|
||||||
gfile.P("Send(msg *", method.Output.Desc.Name(), ") error")
|
gfile.P("Recv() (*", gfile.QualifiedGoIdent(method.Input.GoIdent), ", error)")
|
||||||
}
|
}
|
||||||
if method.Desc.IsStreamingServer() {
|
if method.Desc.IsStreamingServer() {
|
||||||
gfile.P("Recv() (msg *", method.Input.Desc.Name(), ", error)")
|
gfile.P("Send(msg *", gfile.QualifiedGoIdent(method.Output.GoIdent), ") error")
|
||||||
}
|
}
|
||||||
|
gfile.P("}")
|
||||||
|
gfile.P()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateServiceEndpoints(gfile *protogen.GeneratedFile, service *protogen.Service) {
|
func generateServiceEndpoints(gfile *protogen.GeneratedFile, service *protogen.Service) {
|
||||||
serviceName := strings.TrimSuffix(service.GoName, "Service")
|
serviceName := service.GoName
|
||||||
gfile.P("// New", serviceName, "Endpoints provides api endpoints metdata for ", serviceName, " service")
|
gfile.P("func New", serviceName, "Endpoints() []*", microApiPackage.Ident("Endpoint"), " {")
|
||||||
gfile.P("func New", serviceName, "Endpoints() []*micro_api.Endpoint {")
|
gfile.P("return []*", microApiPackage.Ident("Endpoint"), "{")
|
||||||
gfile.P("return []*", "micro_api.Endpoint{")
|
|
||||||
for _, method := range service.Methods {
|
for _, method := range service.Methods {
|
||||||
if method.Desc.Options() == nil {
|
if method.Desc.Options() == nil {
|
||||||
continue
|
continue
|
||||||
@@ -370,7 +438,7 @@ func generateServiceEndpoints(gfile *protogen.GeneratedFile, service *protogen.S
|
|||||||
if proto.HasExtension(method.Desc.Options(), api_options.E_Http) {
|
if proto.HasExtension(method.Desc.Options(), api_options.E_Http) {
|
||||||
endpoints, streaming := generateEndpoints(method)
|
endpoints, streaming := generateEndpoints(method)
|
||||||
for _, endpoint := range endpoints {
|
for _, endpoint := range endpoints {
|
||||||
gfile.P("&", "micro_api.Endpoint{")
|
gfile.P("&", microApiPackage.Ident("Endpoint"), "{")
|
||||||
generateEndpoint(gfile, serviceName, method.GoName, endpoint, streaming)
|
generateEndpoint(gfile, serviceName, method.GoName, endpoint, streaming)
|
||||||
gfile.P("},")
|
gfile.P("},")
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user