This is an automated email from the ASF dual-hosted git repository.
dmwangnima pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-go.git
The following commit(s) were added to refs/heads/main by this push:
new 7683ea455 feat: add reflection service (#2522)
7683ea455 is described below
commit 7683ea455a60752ca4b5912654f228a04bb0b297
Author: finalt <[email protected]>
AuthorDate: Sat Dec 2 10:53:20 2023 +0800
feat: add reflection service (#2522)
* add reflection service
* add license
* fix lint
* fix lint
* fix lint
* update license
* fix comment
* rename reflection.proto
* ignore license
* fix lint
* update proto
---------
Co-authored-by: Ken Liu <[email protected]>
---
Makefile | 2 +-
config/provider_config.go | 56 +-
imports/imports.go | 4 +-
protocol/triple/health/healthServer.go | 1 +
.../internal/client/reflection_client/main.go | 125 +++
protocol/triple/reflection/serverreflection.go | 285 ++++++
.../reflection/triple_reflection/reflection.pb.go | 956 +++++++++++++++++++++
.../reflection/triple_reflection/reflection.proto | 141 +++
.../triple_reflection/reflection.triple.go | 199 +++++
protocol/triple/server.go | 50 +-
protocol/triple/triple.go | 1 +
11 files changed, 1786 insertions(+), 34 deletions(-)
diff --git a/Makefile b/Makefile
index 33dcf68c8..e322a004e 100644
--- a/Makefile
+++ b/Makefile
@@ -63,7 +63,7 @@ deps: prepare
.PHONY: license
license: clean prepareLic
- $(GO_LICENSE_CHECKER) -v -a -r -i
vendor,protocol/triple/triple_protocol,cmd/protoc-gen-go-triple/internal
$(LICENSE_DIR)/license.txt . go && [[ -z `git status -s` ]]
+ $(GO_LICENSE_CHECKER) -v -a -r -i
vendor,protocol/triple/triple_protocol,protocol/triple/reflection,cmd/protoc-gen-go-triple/internal
$(LICENSE_DIR)/license.txt . go && [[ -z `git status -s` ]]
.PHONY: verify
verify: clean license test
diff --git a/config/provider_config.go b/config/provider_config.go
index 7bbb90a58..67889303a 100644
--- a/config/provider_config.go
+++ b/config/provider_config.go
@@ -27,8 +27,6 @@ import (
"github.com/dubbogo/gost/log/logger"
- tripleConstant "github.com/dubbogo/triple/pkg/common/constant"
-
perrors "github.com/pkg/errors"
)
@@ -123,33 +121,33 @@ func (c *ProviderConfig) Init(rc *RootConfig) error {
serviceConfig.adaptiveService = c.AdaptiveService
}
- for k, v := range rc.Protocols {
- if v.Name == tripleConstant.TRIPLE {
- // Auto create grpc based health check service.
- //healthService := NewServiceConfigBuilder().
- // SetProtocolIDs(k).
- // SetNotRegister(true).
- //
SetInterface(constant.HealthCheckServiceInterface).
- // Build()
- //if err := healthService.Init(rc); err != nil {
- // return err
- //}
- //c.Services[constant.HealthCheckServiceTypeName] =
healthService
-
- // Auto create reflection service configure only when
provider with triple service is configured.
- tripleReflectionService := NewServiceConfigBuilder().
- SetProtocolIDs(k).
- SetNotRegister(true).
-
SetInterface(constant.ReflectionServiceInterface).
- Build()
- if err := tripleReflectionService.Init(rc); err != nil {
- return err
- }
- // Maybe only register once, If setting this service,
break from traversing Protocols.
- c.Services[constant.ReflectionServiceTypeName] =
tripleReflectionService
- break
- }
- }
+ //for k, v := range rc.Protocols {
+ // if v.Name == tripleConstant.TRIPLE {
+ // // Auto create grpc based health check service.
+ // healthService := NewServiceConfigBuilder().
+ // SetProtocolIDs(k).
+ // SetNotRegister(true).
+ //
SetInterface(constant.HealthCheckServiceInterface).
+ // Build()
+ // if err := healthService.Init(rc); err != nil {
+ // return err
+ // }
+ // c.Services[constant.HealthCheckServiceTypeName] =
healthService
+ //
+ // // Auto create reflection service configure only when
provider with triple service is configured.
+ // tripleReflectionService := NewServiceConfigBuilder().
+ // SetProtocolIDs(k).
+ // SetNotRegister(true).
+ //
SetInterface(constant.ReflectionServiceInterface).
+ // Build()
+ // if err := tripleReflectionService.Init(rc); err != nil {
+ // return err
+ // }
+ // // Maybe only register once, If setting this service,
break from traversing Protocols.
+ // c.Services[constant.ReflectionServiceTypeName] =
tripleReflectionService
+ // break
+ // }
+ //}
if err := c.check(); err != nil {
return err
diff --git a/imports/imports.go b/imports/imports.go
index 906aced10..39a7197b1 100644
--- a/imports/imports.go
+++ b/imports/imports.go
@@ -72,13 +72,11 @@ import (
_ "dubbo.apache.org/dubbo-go/v3/otel/trace/stdout"
_ "dubbo.apache.org/dubbo-go/v3/otel/trace/zipkin"
_ "dubbo.apache.org/dubbo-go/v3/protocol/dubbo"
- _ "dubbo.apache.org/dubbo-go/v3/protocol/dubbo3"
- _ "dubbo.apache.org/dubbo-go/v3/protocol/dubbo3/reflection"
- _ "dubbo.apache.org/dubbo-go/v3/protocol/grpc"
_ "dubbo.apache.org/dubbo-go/v3/protocol/jsonrpc"
_ "dubbo.apache.org/dubbo-go/v3/protocol/rest"
_ "dubbo.apache.org/dubbo-go/v3/protocol/triple"
_ "dubbo.apache.org/dubbo-go/v3/protocol/triple/health"
+ _ "dubbo.apache.org/dubbo-go/v3/protocol/triple/reflection"
_ "dubbo.apache.org/dubbo-go/v3/proxy/proxy_factory"
_ "dubbo.apache.org/dubbo-go/v3/registry/directory"
_ "dubbo.apache.org/dubbo-go/v3/registry/etcdv3"
diff --git a/protocol/triple/health/healthServer.go
b/protocol/triple/health/healthServer.go
index 43b515af3..7ec228c4e 100644
--- a/protocol/triple/health/healthServer.go
+++ b/protocol/triple/health/healthServer.go
@@ -168,6 +168,7 @@ func init() {
server.SetProServices(&server.ServiceDefinition{
Handler: healthServer,
Info: &triple_health.Health_ServiceInfo,
+ Opts: []server.ServiceOption{server.WithNotRegister()},
})
}
diff --git a/protocol/triple/internal/client/reflection_client/main.go
b/protocol/triple/internal/client/reflection_client/main.go
new file mode 100644
index 000000000..036dc2717
--- /dev/null
+++ b/protocol/triple/internal/client/reflection_client/main.go
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package main
+
+import (
+ "context"
+)
+
+import (
+ "github.com/dubbogo/gost/log/logger"
+
+ "github.com/golang/protobuf/proto"
+
+ "google.golang.org/protobuf/types/descriptorpb"
+)
+
+import (
+ "dubbo.apache.org/dubbo-go/v3/client"
+ _ "dubbo.apache.org/dubbo-go/v3/imports"
+ reflection
"dubbo.apache.org/dubbo-go/v3/protocol/triple/reflection/triple_reflection"
+)
+
+func main() {
+ cli, err := client.NewClient(
+ client.WithClientURL("tri://127.0.0.1:20000"),
+ )
+ if err != nil {
+ panic(err)
+ }
+ svc, err := reflection.NewServerReflection(cli)
+ if err != nil {
+ panic(err)
+ }
+ stream, err := svc.ServerReflectionInfo(context.Background())
+ if err != nil {
+ panic(err)
+ }
+ testReflection(stream)
+}
+
+func testReflection(stream
reflection.ServerReflection_ServerReflectionInfoClient) {
+ if err := testFileByFilename(stream); err != nil {
+ logger.Error(err)
+ }
+ if err := testFileContainingSymbol(stream); err != nil {
+ logger.Error(err)
+ }
+ if err := testListServices(stream); err != nil {
+ logger.Error(err)
+ }
+ if err := stream.CloseRequest(); err != nil {
+ logger.Error(err)
+ }
+ if err := stream.CloseResponse(); err != nil {
+ logger.Error(err)
+ }
+}
+
+func testFileByFilename(stream
reflection.ServerReflection_ServerReflectionInfoClient) error {
+ logger.Info("start to test call FileByFilename")
+ if err := stream.Send(&reflection.ServerReflectionRequest{
+ MessageRequest:
&reflection.ServerReflectionRequest_FileByFilename{FileByFilename:
"reflection.proto"},
+ }); err != nil {
+ return err
+ }
+ recv, err := stream.Recv()
+ if err != nil {
+ return err
+ }
+ m := new(descriptorpb.FileDescriptorProto)
+ if err =
proto.Unmarshal(recv.GetFileDescriptorResponse().GetFileDescriptorProto()[0],
m); err != nil {
+ return err
+ }
+ logger.Infof("call FileByFilename 's resp : %s", m)
+ return nil
+}
+
+func testFileContainingSymbol(stream
reflection.ServerReflection_ServerReflectionInfoClient) error {
+ logger.Info("start to test call FileContainingSymbol")
+ if err := stream.Send(&reflection.ServerReflectionRequest{
+ MessageRequest:
&reflection.ServerReflectionRequest_FileContainingSymbol{FileContainingSymbol:
"dubbo.reflection.v1alpha.ServerReflection"},
+ }); err != nil {
+ return err
+ }
+ recv, err := stream.Recv()
+ if err != nil {
+ return err
+ }
+ m := new(descriptorpb.FileDescriptorProto)
+ if err =
proto.Unmarshal(recv.GetFileDescriptorResponse().GetFileDescriptorProto()[0],
m); err != nil {
+ return err
+ }
+ logger.Infof("call FileContainingSymbol 's resp : %s", m)
+ return nil
+}
+
+func testListServices(stream
reflection.ServerReflection_ServerReflectionInfoClient) error {
+ logger.Info("start to test call ListServices")
+ if err := stream.Send(&reflection.ServerReflectionRequest{
+ MessageRequest:
&reflection.ServerReflectionRequest_ListServices{},
+ }); err != nil {
+ return err
+ }
+ recv, err := stream.Recv()
+ if err != nil {
+ return err
+ }
+ logger.Infof("call ListServices 's resp : %s",
recv.GetListServicesResponse().GetService())
+ return nil
+}
diff --git a/protocol/triple/reflection/serverreflection.go
b/protocol/triple/reflection/serverreflection.go
new file mode 100644
index 000000000..de2816b33
--- /dev/null
+++ b/protocol/triple/reflection/serverreflection.go
@@ -0,0 +1,285 @@
+/*
+ *
+ * Copyright 2016 gRPC authors.
+ *
+ * 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.
+ *
+ */
+
+package reflection
+
+import (
+ "context"
+ "io"
+ "sort"
+)
+
+import (
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
+
+ "google.golang.org/protobuf/proto"
+
+ "google.golang.org/protobuf/reflect/protodesc"
+ "google.golang.org/protobuf/reflect/protoreflect"
+ "google.golang.org/protobuf/reflect/protoregistry"
+)
+
+import (
+ rpb
"dubbo.apache.org/dubbo-go/v3/protocol/triple/reflection/triple_reflection"
+ "dubbo.apache.org/dubbo-go/v3/server"
+)
+
+// ServiceInfoProvider is an interface used to retrieve metadata about the
+// services to expose.
+//
+// The reflection service is only interested in the service names, but the
+// signature is this way so that *grpc.Server implements it. So it is okay
+// for a custom implementation to return zero values for the
+// grpc.ServiceInfo values in the map.
+//
+// # Experimental
+//
+// Notice: This type is EXPERIMENTAL and may be changed or removed in a
+// later release.
+type ServiceInfoProvider interface {
+ GetServiceInfo() map[string]grpc.ServiceInfo
+}
+
+// ExtensionResolver is the interface used to query details about extensions.
+// This interface is satisfied by protoregistry.GlobalTypes.
+//
+// # Experimental
+//
+// Notice: This type is EXPERIMENTAL and may be changed or removed in a
+// later release.
+type ExtensionResolver interface {
+ protoregistry.ExtensionTypeResolver
+ RangeExtensionsByMessage(message protoreflect.FullName, f
func(protoreflect.ExtensionType) bool)
+}
+
+func NewServer() *ReflectionServer {
+ return &ReflectionServer{
+ descResolver: protoregistry.GlobalFiles,
+ extResolver: protoregistry.GlobalTypes,
+ }
+}
+
+type ReflectionServer struct {
+ s ServiceInfoProvider
+ descResolver protodesc.Resolver
+ extResolver ExtensionResolver
+}
+
+// fileDescWithDependencies returns a slice of serialized fileDescriptors in
+// wire format ([]byte). The fileDescriptors will include fd and all the
+// transitive dependencies of fd with names not in sentFileDescriptors.
+func (s *ReflectionServer) fileDescWithDependencies(fd
protoreflect.FileDescriptor, sentFileDescriptors map[string]bool) ([][]byte,
error) {
+ if fd.IsPlaceholder() {
+ // If the given root file is a placeholder, treat it
+ // as missing instead of serializing it.
+ return nil, protoregistry.NotFound
+ }
+ var r [][]byte
+ queue := []protoreflect.FileDescriptor{fd}
+ for len(queue) > 0 {
+ currentfd := queue[0]
+ queue = queue[1:]
+ if currentfd.IsPlaceholder() {
+ // Skip any missing files in the dependency graph.
+ continue
+ }
+ if sent := sentFileDescriptors[currentfd.Path()]; len(r) == 0
|| !sent {
+ sentFileDescriptors[currentfd.Path()] = true
+ fdProto := protodesc.ToFileDescriptorProto(currentfd)
+ currentfdEncoded, err := proto.Marshal(fdProto)
+ if err != nil {
+ return nil, err
+ }
+ r = append(r, currentfdEncoded)
+ }
+ for i := 0; i < currentfd.Imports().Len(); i++ {
+ queue = append(queue, currentfd.Imports().Get(i))
+ }
+ }
+ return r, nil
+}
+
+// fileDescEncodingContainingSymbol finds the file descriptor containing the
+// given symbol, finds all of its previously unsent transitive dependencies,
+// does marshaling on them, and returns the marshaled result. The given symbol
+// can be a type, a service or a method.
+func (s *ReflectionServer) fileDescEncodingContainingSymbol(name string,
sentFileDescriptors map[string]bool) ([][]byte, error) {
+ d, err :=
s.descResolver.FindDescriptorByName(protoreflect.FullName(name))
+ if err != nil {
+ return nil, err
+ }
+ return s.fileDescWithDependencies(d.ParentFile(), sentFileDescriptors)
+}
+
+// fileDescEncodingContainingExtension finds the file descriptor containing
+// given extension, finds all of its previously unsent transitive dependencies,
+// does marshaling on them, and returns the marshaled result.
+func (s *ReflectionServer) fileDescEncodingContainingExtension(typeName
string, extNum int32, sentFileDescriptors map[string]bool) ([][]byte, error) {
+ xt, err :=
s.extResolver.FindExtensionByNumber(protoreflect.FullName(typeName),
protoreflect.FieldNumber(extNum))
+ if err != nil {
+ return nil, err
+ }
+ return s.fileDescWithDependencies(xt.TypeDescriptor().ParentFile(),
sentFileDescriptors)
+}
+
+// allExtensionNumbersForTypeName returns all extension numbers for the given
type.
+func (s *ReflectionServer) allExtensionNumbersForTypeName(name string)
([]int32, error) {
+ var numbers []int32
+ s.extResolver.RangeExtensionsByMessage(protoreflect.FullName(name),
func(xt protoreflect.ExtensionType) bool {
+ numbers = append(numbers, int32(xt.TypeDescriptor().Number()))
+ return true
+ })
+ sort.Slice(numbers, func(i, j int) bool {
+ return numbers[i] < numbers[j]
+ })
+ if len(numbers) == 0 {
+ // maybe return an error if given type name is not known
+ if _, err :=
s.descResolver.FindDescriptorByName(protoreflect.FullName(name)); err != nil {
+ return nil, err
+ }
+ }
+ return numbers, nil
+}
+
+// listServices returns the names of services this server exposes.
+func (s *ReflectionServer) listServices() []*rpb.ServiceResponse {
+ serviceInfo := s.s.GetServiceInfo()
+ resp := make([]*rpb.ServiceResponse, 0, len(serviceInfo))
+ for svc := range serviceInfo {
+ resp = append(resp, &rpb.ServiceResponse{Name: svc})
+ }
+ sort.Slice(resp, func(i, j int) bool {
+ return resp[i].Name < resp[j].Name
+ })
+ return resp
+}
+
+// ServerReflectionInfo is the reflection service handler.
+func (s *ReflectionServer) ServerReflectionInfo(ctx context.Context, stream
rpb.ServerReflection_ServerReflectionInfoServer) error {
+ sentFileDescriptors := make(map[string]bool)
+ for {
+ in, err := stream.Recv()
+ if err == io.EOF {
+ return nil
+ }
+ if err != nil {
+ return err
+ }
+
+ out := &rpb.ServerReflectionResponse{
+ ValidHost: in.Host,
+ OriginalRequest: in,
+ }
+ switch req := in.MessageRequest.(type) {
+ case *rpb.ServerReflectionRequest_FileByFilename:
+ var b [][]byte
+ fd, err :=
s.descResolver.FindFileByPath(req.FileByFilename)
+ if err == nil {
+ b, err = s.fileDescWithDependencies(fd,
sentFileDescriptors)
+ }
+ if err != nil {
+ out.MessageResponse =
&rpb.ServerReflectionResponse_ErrorResponse{
+ ErrorResponse: &rpb.ErrorResponse{
+ ErrorCode:
int32(codes.NotFound),
+ ErrorMessage: err.Error(),
+ },
+ }
+ } else {
+ out.MessageResponse =
&rpb.ServerReflectionResponse_FileDescriptorResponse{
+ FileDescriptorResponse:
&rpb.FileDescriptorResponse{FileDescriptorProto: b},
+ }
+ }
+ case *rpb.ServerReflectionRequest_FileContainingSymbol:
+ b, err :=
s.fileDescEncodingContainingSymbol(req.FileContainingSymbol,
sentFileDescriptors)
+ if err != nil {
+ out.MessageResponse =
&rpb.ServerReflectionResponse_ErrorResponse{
+ ErrorResponse: &rpb.ErrorResponse{
+ ErrorCode:
int32(codes.NotFound),
+ ErrorMessage: err.Error(),
+ },
+ }
+ } else {
+ out.MessageResponse =
&rpb.ServerReflectionResponse_FileDescriptorResponse{
+ FileDescriptorResponse:
&rpb.FileDescriptorResponse{FileDescriptorProto: b},
+ }
+ }
+ case *rpb.ServerReflectionRequest_FileContainingExtension:
+ typeName := req.FileContainingExtension.ContainingType
+ extNum := req.FileContainingExtension.ExtensionNumber
+ b, err :=
s.fileDescEncodingContainingExtension(typeName, extNum, sentFileDescriptors)
+ if err != nil {
+ out.MessageResponse =
&rpb.ServerReflectionResponse_ErrorResponse{
+ ErrorResponse: &rpb.ErrorResponse{
+ ErrorCode:
int32(codes.NotFound),
+ ErrorMessage: err.Error(),
+ },
+ }
+ } else {
+ out.MessageResponse =
&rpb.ServerReflectionResponse_FileDescriptorResponse{
+ FileDescriptorResponse:
&rpb.FileDescriptorResponse{FileDescriptorProto: b},
+ }
+ }
+ case *rpb.ServerReflectionRequest_AllExtensionNumbersOfType:
+ extNums, err :=
s.allExtensionNumbersForTypeName(req.AllExtensionNumbersOfType)
+ if err != nil {
+ out.MessageResponse =
&rpb.ServerReflectionResponse_ErrorResponse{
+ ErrorResponse: &rpb.ErrorResponse{
+ ErrorCode:
int32(codes.NotFound),
+ ErrorMessage: err.Error(),
+ },
+ }
+ } else {
+ out.MessageResponse =
&rpb.ServerReflectionResponse_AllExtensionNumbersResponse{
+ AllExtensionNumbersResponse:
&rpb.ExtensionNumberResponse{
+ BaseTypeName:
req.AllExtensionNumbersOfType,
+ ExtensionNumber: extNums,
+ },
+ }
+ }
+ case *rpb.ServerReflectionRequest_ListServices:
+ out.MessageResponse =
&rpb.ServerReflectionResponse_ListServicesResponse{
+ ListServicesResponse: &rpb.ListServiceResponse{
+ Service: s.listServices(),
+ },
+ }
+ default:
+ return status.Errorf(codes.InvalidArgument, "invalid
MessageRequest: %v", in.MessageRequest)
+ }
+
+ if err := stream.Send(out); err != nil {
+ return err
+ }
+ }
+}
+
+var reflectionServe *ReflectionServer
+
+func init() {
+ reflectionServe = NewServer()
+ server.SetProServices(&server.ServiceDefinition{
+ Handler: reflectionServe,
+ Info: &rpb.ServerReflection_ServiceInfo,
+ Opts: []server.ServiceOption{server.WithNotRegister()},
+ })
+}
+
+func Register(s ServiceInfoProvider) {
+ reflectionServe.s = s
+}
diff --git a/protocol/triple/reflection/triple_reflection/reflection.pb.go
b/protocol/triple/reflection/triple_reflection/reflection.pb.go
new file mode 100644
index 000000000..2e66e7108
--- /dev/null
+++ b/protocol/triple/reflection/triple_reflection/reflection.pb.go
@@ -0,0 +1,956 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+// Service exported by server reflection
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.29.0
+// protoc v3.15.5
+// source: reflection.proto
+
+package triple_reflection
+
+import (
+ reflect "reflect"
+ sync "sync"
+)
+
+import (
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// The message sent by the client when calling ServerReflectionInfo method.
+type ServerReflectionRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Host string `protobuf:"bytes,1,opt,name=host,proto3"
json:"host,omitempty"`
+ // To use reflection service, the client should set one of the following
+ // fields in message_request. The server distinguishes requests by their
+ // defined field and then handles them using corresponding methods.
+ //
+ // Types that are assignable to MessageRequest:
+ //
+ // *ServerReflectionRequest_FileByFilename
+ // *ServerReflectionRequest_FileContainingSymbol
+ // *ServerReflectionRequest_FileContainingExtension
+ // *ServerReflectionRequest_AllExtensionNumbersOfType
+ // *ServerReflectionRequest_ListServices
+ MessageRequest isServerReflectionRequest_MessageRequest
`protobuf_oneof:"message_request"`
+}
+
+func (x *ServerReflectionRequest) Reset() {
+ *x = ServerReflectionRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_reflection_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ServerReflectionRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ServerReflectionRequest) ProtoMessage() {}
+
+func (x *ServerReflectionRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_reflection_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ServerReflectionRequest.ProtoReflect.Descriptor instead.
+func (*ServerReflectionRequest) Descriptor() ([]byte, []int) {
+ return file_reflection_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *ServerReflectionRequest) GetHost() string {
+ if x != nil {
+ return x.Host
+ }
+ return ""
+}
+
+func (m *ServerReflectionRequest) GetMessageRequest()
isServerReflectionRequest_MessageRequest {
+ if m != nil {
+ return m.MessageRequest
+ }
+ return nil
+}
+
+func (x *ServerReflectionRequest) GetFileByFilename() string {
+ if x, ok :=
x.GetMessageRequest().(*ServerReflectionRequest_FileByFilename); ok {
+ return x.FileByFilename
+ }
+ return ""
+}
+
+func (x *ServerReflectionRequest) GetFileContainingSymbol() string {
+ if x, ok :=
x.GetMessageRequest().(*ServerReflectionRequest_FileContainingSymbol); ok {
+ return x.FileContainingSymbol
+ }
+ return ""
+}
+
+func (x *ServerReflectionRequest) GetFileContainingExtension()
*ExtensionRequest {
+ if x, ok :=
x.GetMessageRequest().(*ServerReflectionRequest_FileContainingExtension); ok {
+ return x.FileContainingExtension
+ }
+ return nil
+}
+
+func (x *ServerReflectionRequest) GetAllExtensionNumbersOfType() string {
+ if x, ok :=
x.GetMessageRequest().(*ServerReflectionRequest_AllExtensionNumbersOfType); ok {
+ return x.AllExtensionNumbersOfType
+ }
+ return ""
+}
+
+func (x *ServerReflectionRequest) GetListServices() string {
+ if x, ok :=
x.GetMessageRequest().(*ServerReflectionRequest_ListServices); ok {
+ return x.ListServices
+ }
+ return ""
+}
+
+type isServerReflectionRequest_MessageRequest interface {
+ isServerReflectionRequest_MessageRequest()
+}
+
+type ServerReflectionRequest_FileByFilename struct {
+ // Find a proto file by the file name.
+ FileByFilename string
`protobuf:"bytes,3,opt,name=file_by_filename,json=fileByFilename,proto3,oneof"`
+}
+
+type ServerReflectionRequest_FileContainingSymbol struct {
+ // Find the proto file that declares the given fully-qualified symbol
name.
+ // This field should be a fully-qualified symbol name
+ // (e.g. <package>.<service>[.<method>] or <package>.<type>).
+ FileContainingSymbol string
`protobuf:"bytes,4,opt,name=file_containing_symbol,json=fileContainingSymbol,proto3,oneof"`
+}
+
+type ServerReflectionRequest_FileContainingExtension struct {
+ // Find the proto file which defines an extension extending the given
+ // message type with the given field number.
+ FileContainingExtension *ExtensionRequest
`protobuf:"bytes,5,opt,name=file_containing_extension,json=fileContainingExtension,proto3,oneof"`
+}
+
+type ServerReflectionRequest_AllExtensionNumbersOfType struct {
+ // Finds the tag numbers used by all known extensions of extendee_type,
and
+ // appends them to ExtensionNumberResponse in an undefined order.
+ // Its corresponding method is best-effort: it's not guaranteed that the
+ // reflection service will implement this method, and it's not
guaranteed
+ // that this method will provide all extensions. Returns
+ // StatusCode::UNIMPLEMENTED if it's not implemented.
+ // This field should be a fully-qualified type name. The format is
+ // <package>.<type>
+ AllExtensionNumbersOfType string
`protobuf:"bytes,6,opt,name=all_extension_numbers_of_type,json=allExtensionNumbersOfType,proto3,oneof"`
+}
+
+type ServerReflectionRequest_ListServices struct {
+ // List the full names of registered services. The content will not be
+ // checked.
+ ListServices string
`protobuf:"bytes,7,opt,name=list_services,json=listServices,proto3,oneof"`
+}
+
+func (*ServerReflectionRequest_FileByFilename)
isServerReflectionRequest_MessageRequest() {}
+
+func (*ServerReflectionRequest_FileContainingSymbol)
isServerReflectionRequest_MessageRequest() {}
+
+func (*ServerReflectionRequest_FileContainingExtension)
isServerReflectionRequest_MessageRequest() {}
+
+func (*ServerReflectionRequest_AllExtensionNumbersOfType)
isServerReflectionRequest_MessageRequest() {
+}
+
+func (*ServerReflectionRequest_ListServices)
isServerReflectionRequest_MessageRequest() {}
+
+// The type name and extension number sent by the client when requesting
+// file_containing_extension.
+type ExtensionRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Fully-qualified type name. The format should be <package>.<type>
+ ContainingType string
`protobuf:"bytes,1,opt,name=containing_type,json=containingType,proto3"
json:"containing_type,omitempty"`
+ ExtensionNumber int32
`protobuf:"varint,2,opt,name=extension_number,json=extensionNumber,proto3"
json:"extension_number,omitempty"`
+}
+
+func (x *ExtensionRequest) Reset() {
+ *x = ExtensionRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_reflection_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ExtensionRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ExtensionRequest) ProtoMessage() {}
+
+func (x *ExtensionRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_reflection_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ExtensionRequest.ProtoReflect.Descriptor instead.
+func (*ExtensionRequest) Descriptor() ([]byte, []int) {
+ return file_reflection_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *ExtensionRequest) GetContainingType() string {
+ if x != nil {
+ return x.ContainingType
+ }
+ return ""
+}
+
+func (x *ExtensionRequest) GetExtensionNumber() int32 {
+ if x != nil {
+ return x.ExtensionNumber
+ }
+ return 0
+}
+
+// The message sent by the server to answer ServerReflectionInfo method.
+type ServerReflectionResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ ValidHost string
`protobuf:"bytes,1,opt,name=valid_host,json=validHost,proto3"
json:"valid_host,omitempty"`
+ OriginalRequest *ServerReflectionRequest
`protobuf:"bytes,2,opt,name=original_request,json=originalRequest,proto3"
json:"original_request,omitempty"`
+ // The server sets one of the following fields according to the
+ // message_request in the request.
+ //
+ // Types that are assignable to MessageResponse:
+ //
+ // *ServerReflectionResponse_FileDescriptorResponse
+ // *ServerReflectionResponse_AllExtensionNumbersResponse
+ // *ServerReflectionResponse_ListServicesResponse
+ // *ServerReflectionResponse_ErrorResponse
+ MessageResponse isServerReflectionResponse_MessageResponse
`protobuf_oneof:"message_response"`
+}
+
+func (x *ServerReflectionResponse) Reset() {
+ *x = ServerReflectionResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_reflection_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ServerReflectionResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ServerReflectionResponse) ProtoMessage() {}
+
+func (x *ServerReflectionResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_reflection_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ServerReflectionResponse.ProtoReflect.Descriptor instead.
+func (*ServerReflectionResponse) Descriptor() ([]byte, []int) {
+ return file_reflection_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *ServerReflectionResponse) GetValidHost() string {
+ if x != nil {
+ return x.ValidHost
+ }
+ return ""
+}
+
+func (x *ServerReflectionResponse) GetOriginalRequest()
*ServerReflectionRequest {
+ if x != nil {
+ return x.OriginalRequest
+ }
+ return nil
+}
+
+func (m *ServerReflectionResponse) GetMessageResponse()
isServerReflectionResponse_MessageResponse {
+ if m != nil {
+ return m.MessageResponse
+ }
+ return nil
+}
+
+func (x *ServerReflectionResponse) GetFileDescriptorResponse()
*FileDescriptorResponse {
+ if x, ok :=
x.GetMessageResponse().(*ServerReflectionResponse_FileDescriptorResponse); ok {
+ return x.FileDescriptorResponse
+ }
+ return nil
+}
+
+func (x *ServerReflectionResponse) GetAllExtensionNumbersResponse()
*ExtensionNumberResponse {
+ if x, ok :=
x.GetMessageResponse().(*ServerReflectionResponse_AllExtensionNumbersResponse);
ok {
+ return x.AllExtensionNumbersResponse
+ }
+ return nil
+}
+
+func (x *ServerReflectionResponse) GetListServicesResponse()
*ListServiceResponse {
+ if x, ok :=
x.GetMessageResponse().(*ServerReflectionResponse_ListServicesResponse); ok {
+ return x.ListServicesResponse
+ }
+ return nil
+}
+
+func (x *ServerReflectionResponse) GetErrorResponse() *ErrorResponse {
+ if x, ok :=
x.GetMessageResponse().(*ServerReflectionResponse_ErrorResponse); ok {
+ return x.ErrorResponse
+ }
+ return nil
+}
+
+type isServerReflectionResponse_MessageResponse interface {
+ isServerReflectionResponse_MessageResponse()
+}
+
+type ServerReflectionResponse_FileDescriptorResponse struct {
+ // This message is used to answer file_by_filename,
file_containing_symbol,
+ // file_containing_extension requests with transitive dependencies.
+ // As the repeated label is not allowed in oneof fields, we use a
+ // FileDescriptorResponse message to encapsulate the repeated fields.
+ // The reflection service is allowed to avoid sending
FileDescriptorProtos
+ // that were previously sent in response to earlier requests in the
stream.
+ FileDescriptorResponse *FileDescriptorResponse
`protobuf:"bytes,4,opt,name=file_descriptor_response,json=fileDescriptorResponse,proto3,oneof"`
+}
+
+type ServerReflectionResponse_AllExtensionNumbersResponse struct {
+ // This message is used to answer all_extension_numbers_of_type
requests.
+ AllExtensionNumbersResponse *ExtensionNumberResponse
`protobuf:"bytes,5,opt,name=all_extension_numbers_response,json=allExtensionNumbersResponse,proto3,oneof"`
+}
+
+type ServerReflectionResponse_ListServicesResponse struct {
+ // This message is used to answer list_services requests.
+ ListServicesResponse *ListServiceResponse
`protobuf:"bytes,6,opt,name=list_services_response,json=listServicesResponse,proto3,oneof"`
+}
+
+type ServerReflectionResponse_ErrorResponse struct {
+ // This message is used when an error occurs.
+ ErrorResponse *ErrorResponse
`protobuf:"bytes,7,opt,name=error_response,json=errorResponse,proto3,oneof"`
+}
+
+func (*ServerReflectionResponse_FileDescriptorResponse)
isServerReflectionResponse_MessageResponse() {
+}
+
+func (*ServerReflectionResponse_AllExtensionNumbersResponse)
isServerReflectionResponse_MessageResponse() {
+}
+
+func (*ServerReflectionResponse_ListServicesResponse)
isServerReflectionResponse_MessageResponse() {}
+
+func (*ServerReflectionResponse_ErrorResponse)
isServerReflectionResponse_MessageResponse() {}
+
+// Serialized FileDescriptorProto messages sent by the server answering
+// a file_by_filename, file_containing_symbol, or file_containing_extension
+// request.
+type FileDescriptorResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Serialized FileDescriptorProto messages. We avoid taking a
dependency on
+ // descriptor.proto, which uses proto2 only features, by making them
opaque
+ // bytes instead.
+ FileDescriptorProto [][]byte
`protobuf:"bytes,1,rep,name=file_descriptor_proto,json=fileDescriptorProto,proto3"
json:"file_descriptor_proto,omitempty"`
+}
+
+func (x *FileDescriptorResponse) Reset() {
+ *x = FileDescriptorResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_reflection_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *FileDescriptorResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FileDescriptorResponse) ProtoMessage() {}
+
+func (x *FileDescriptorResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_reflection_proto_msgTypes[3]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use FileDescriptorResponse.ProtoReflect.Descriptor instead.
+func (*FileDescriptorResponse) Descriptor() ([]byte, []int) {
+ return file_reflection_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *FileDescriptorResponse) GetFileDescriptorProto() [][]byte {
+ if x != nil {
+ return x.FileDescriptorProto
+ }
+ return nil
+}
+
+// A list of extension numbers sent by the server answering
+// all_extension_numbers_of_type request.
+type ExtensionNumberResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Full name of the base type, including the package name. The format
+ // is <package>.<type>
+ BaseTypeName string
`protobuf:"bytes,1,opt,name=base_type_name,json=baseTypeName,proto3"
json:"base_type_name,omitempty"`
+ ExtensionNumber []int32
`protobuf:"varint,2,rep,packed,name=extension_number,json=extensionNumber,proto3"
json:"extension_number,omitempty"`
+}
+
+func (x *ExtensionNumberResponse) Reset() {
+ *x = ExtensionNumberResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_reflection_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ExtensionNumberResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ExtensionNumberResponse) ProtoMessage() {}
+
+func (x *ExtensionNumberResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_reflection_proto_msgTypes[4]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ExtensionNumberResponse.ProtoReflect.Descriptor instead.
+func (*ExtensionNumberResponse) Descriptor() ([]byte, []int) {
+ return file_reflection_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *ExtensionNumberResponse) GetBaseTypeName() string {
+ if x != nil {
+ return x.BaseTypeName
+ }
+ return ""
+}
+
+func (x *ExtensionNumberResponse) GetExtensionNumber() []int32 {
+ if x != nil {
+ return x.ExtensionNumber
+ }
+ return nil
+}
+
+// A list of ServiceResponse sent by the server answering list_services
request.
+type ListServiceResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // The information of each service may be expanded in the future, so we
use
+ // ServiceResponse message to encapsulate it.
+ Service []*ServiceResponse `protobuf:"bytes,1,rep,name=service,proto3"
json:"service,omitempty"`
+}
+
+func (x *ListServiceResponse) Reset() {
+ *x = ListServiceResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_reflection_proto_msgTypes[5]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ListServiceResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ListServiceResponse) ProtoMessage() {}
+
+func (x *ListServiceResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_reflection_proto_msgTypes[5]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ListServiceResponse.ProtoReflect.Descriptor instead.
+func (*ListServiceResponse) Descriptor() ([]byte, []int) {
+ return file_reflection_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *ListServiceResponse) GetService() []*ServiceResponse {
+ if x != nil {
+ return x.Service
+ }
+ return nil
+}
+
+// The information of a single service used by ListServiceResponse to answer
+// list_services request.
+type ServiceResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Full name of a registered service, including its package name. The
format
+ // is <package>.<service>
+ Name string `protobuf:"bytes,1,opt,name=name,proto3"
json:"name,omitempty"`
+}
+
+func (x *ServiceResponse) Reset() {
+ *x = ServiceResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_reflection_proto_msgTypes[6]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ServiceResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ServiceResponse) ProtoMessage() {}
+
+func (x *ServiceResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_reflection_proto_msgTypes[6]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ServiceResponse.ProtoReflect.Descriptor instead.
+func (*ServiceResponse) Descriptor() ([]byte, []int) {
+ return file_reflection_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *ServiceResponse) GetName() string {
+ if x != nil {
+ return x.Name
+ }
+ return ""
+}
+
+// The error code and error message sent by the server when an error occurs.
+type ErrorResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // This field uses the error codes defined in grpc::StatusCode.
+ ErrorCode int32
`protobuf:"varint,1,opt,name=error_code,json=errorCode,proto3"
json:"error_code,omitempty"`
+ ErrorMessage string
`protobuf:"bytes,2,opt,name=error_message,json=errorMessage,proto3"
json:"error_message,omitempty"`
+}
+
+func (x *ErrorResponse) Reset() {
+ *x = ErrorResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_reflection_proto_msgTypes[7]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ErrorResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ErrorResponse) ProtoMessage() {}
+
+func (x *ErrorResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_reflection_proto_msgTypes[7]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ErrorResponse.ProtoReflect.Descriptor instead.
+func (*ErrorResponse) Descriptor() ([]byte, []int) {
+ return file_reflection_proto_rawDescGZIP(), []int{7}
+}
+
+func (x *ErrorResponse) GetErrorCode() int32 {
+ if x != nil {
+ return x.ErrorCode
+ }
+ return 0
+}
+
+func (x *ErrorResponse) GetErrorMessage() string {
+ if x != nil {
+ return x.ErrorMessage
+ }
+ return ""
+}
+
+var File_reflection_proto protoreflect.FileDescriptor
+
+var file_reflection_proto_rawDesc = []byte{
+ 0x0a, 0x10, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x12, 0x18, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x72, 0x65,
0x66, 0x6c, 0x65, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
0x22, 0xf9, 0x02, 0x0a,
+ 0x17, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x66, 0x6c, 0x65,
0x63, 0x74, 0x69, 0x6f,
+ 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04,
0x68, 0x6f, 0x73, 0x74,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74,
0x12, 0x2a, 0x0a, 0x10,
+ 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x62, 0x79, 0x5f, 0x66, 0x69, 0x6c, 0x65,
0x6e, 0x61, 0x6d, 0x65,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0e, 0x66, 0x69,
0x6c, 0x65, 0x42, 0x79,
+ 0x46, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x16,
0x66, 0x69, 0x6c, 0x65,
+ 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x5f,
0x73, 0x79, 0x6d, 0x62,
+ 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x14,
0x66, 0x69, 0x6c, 0x65,
+ 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x53, 0x79,
0x6d, 0x62, 0x6f, 0x6c,
+ 0x12, 0x68, 0x0a, 0x19, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e,
0x74, 0x61, 0x69, 0x6e,
+ 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,
0x6e, 0x18, 0x05, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e,
0x72, 0x65, 0x66, 0x6c,
+ 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
0x68, 0x61, 0x2e, 0x45,
+ 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x48,
+ 0x00, 0x52, 0x17, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61,
0x69, 0x6e, 0x69, 0x6e,
+ 0x67, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x42,
0x0a, 0x1d, 0x61, 0x6c,
+ 0x6c, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f,
0x6e, 0x75, 0x6d, 0x62,
+ 0x65, 0x72, 0x73, 0x5f, 0x6f, 0x66, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18,
0x06, 0x20, 0x01, 0x28,
+ 0x09, 0x48, 0x00, 0x52, 0x19, 0x61, 0x6c, 0x6c, 0x45, 0x78, 0x74, 0x65,
0x6e, 0x73, 0x69, 0x6f,
+ 0x6e, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x4f, 0x66, 0x54, 0x79,
0x70, 0x65, 0x12, 0x25,
+ 0x0a, 0x0d, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x73, 0x18,
+ 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0c, 0x6c, 0x69, 0x73,
0x74, 0x53, 0x65, 0x72,
+ 0x76, 0x69, 0x63, 0x65, 0x73, 0x42, 0x11, 0x0a, 0x0f, 0x6d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65,
+ 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x66, 0x0a, 0x10,
0x45, 0x78, 0x74, 0x65,
+ 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x12, 0x27, 0x0a, 0x0f,
+ 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x74,
0x79, 0x70, 0x65, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x61,
0x69, 0x6e, 0x69, 0x6e,
+ 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x78, 0x74,
0x65, 0x6e, 0x73, 0x69,
+ 0x6f, 0x6e, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20,
0x01, 0x28, 0x05, 0x52,
+ 0x0f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x4e, 0x75,
0x6d, 0x62, 0x65, 0x72,
+ 0x22, 0xcc, 0x04, 0x0a, 0x18, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52,
0x65, 0x66, 0x6c, 0x65,
+ 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x1d, 0x0a,
+ 0x0a, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x18,
0x01, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x09, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x48, 0x6f, 0x73, 0x74,
0x12, 0x5c, 0x0a, 0x10,
+ 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x64, 0x75, 0x62,
0x62, 0x6f, 0x2e, 0x72,
+ 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31,
0x61, 0x6c, 0x70, 0x68,
+ 0x61, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x66, 0x6c,
0x65, 0x63, 0x74, 0x69,
+ 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0f, 0x6f,
0x72, 0x69, 0x67, 0x69,
+ 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x6c,
0x0a, 0x18, 0x66, 0x69,
+ 0x6c, 0x65, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f,
0x72, 0x5f, 0x72, 0x65,
+ 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x30, 0x2e, 0x64,
+ 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x2e,
+ 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x46, 0x69, 0x6c, 0x65,
0x44, 0x65, 0x73, 0x63,
+ 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x48, 0x00,
+ 0x52, 0x16, 0x66, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69,
0x70, 0x74, 0x6f, 0x72,
+ 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x1e,
0x61, 0x6c, 0x6c, 0x5f,
+ 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x75,
0x6d, 0x62, 0x65, 0x72,
+ 0x73, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x05,
0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x31, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x72, 0x65, 0x66,
0x6c, 0x65, 0x63, 0x74,
+ 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e,
0x45, 0x78, 0x74, 0x65,
+ 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x52,
0x65, 0x73, 0x70, 0x6f,
+ 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x1b, 0x61, 0x6c, 0x6c, 0x45, 0x78,
0x74, 0x65, 0x6e, 0x73,
+ 0x69, 0x6f, 0x6e, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e,
+ 0x73, 0x65, 0x12, 0x65, 0x0a, 0x16, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x73,
0x65, 0x72, 0x76, 0x69,
+ 0x63, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x18, 0x06, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x72,
0x65, 0x66, 0x6c, 0x65,
+ 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
0x61, 0x2e, 0x4c, 0x69,
+ 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73,
+ 0x65, 0x48, 0x00, 0x52, 0x14, 0x6c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72,
0x76, 0x69, 0x63, 0x65,
+ 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a,
0x0e, 0x65, 0x72, 0x72,
+ 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18,
0x07, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x27, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x72, 0x65,
0x66, 0x6c, 0x65, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
0x2e, 0x45, 0x72, 0x72,
+ 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00,
0x52, 0x0d, 0x65, 0x72,
+ 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42,
0x12, 0x0a, 0x10, 0x6d,
+ 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22,
+ 0x4c, 0x0a, 0x16, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72,
0x69, 0x70, 0x74, 0x6f,
+ 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a,
0x15, 0x66, 0x69, 0x6c,
+ 0x65, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72,
0x5f, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x13, 0x66, 0x69,
0x6c, 0x65, 0x44, 0x65,
+ 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74,
0x6f, 0x22, 0x6a, 0x0a,
+ 0x17, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x4e, 0x75,
0x6d, 0x62, 0x65, 0x72,
+ 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x0e,
0x62, 0x61, 0x73, 0x65,
+ 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x0c, 0x62, 0x61, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x4e, 0x61,
0x6d, 0x65, 0x12, 0x29,
+ 0x0a, 0x10, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f,
0x6e, 0x75, 0x6d, 0x62,
+ 0x65, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x05, 0x52, 0x0f, 0x65, 0x78,
0x74, 0x65, 0x6e, 0x73,
+ 0x69, 0x6f, 0x6e, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x5a, 0x0a,
0x13, 0x4c, 0x69, 0x73,
+ 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65,
+ 0x12, 0x43, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18,
0x01, 0x20, 0x03, 0x28,
+ 0x0b, 0x32, 0x29, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x72, 0x65,
0x66, 0x6c, 0x65, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
0x2e, 0x53, 0x65, 0x72,
+ 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x52, 0x07, 0x73, 0x65,
+ 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x25, 0x0a, 0x0f, 0x53, 0x65, 0x72,
0x76, 0x69, 0x63, 0x65,
+ 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04,
0x6e, 0x61, 0x6d, 0x65,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
0x22, 0x53, 0x0a, 0x0d,
+ 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x1d, 0x0a,
+ 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18,
0x01, 0x20, 0x01, 0x28,
+ 0x05, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65,
0x12, 0x23, 0x0a, 0x0d,
+ 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65,
0x73, 0x73, 0x61, 0x67,
+ 0x65, 0x32, 0x96, 0x01, 0x0a, 0x10, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
0x52, 0x65, 0x66, 0x6c,
+ 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x81, 0x01, 0x0a, 0x14, 0x53,
0x65, 0x72, 0x76, 0x65,
+ 0x72, 0x52, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49,
0x6e, 0x66, 0x6f, 0x12,
+ 0x31, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x72, 0x65, 0x66, 0x6c,
0x65, 0x63, 0x74, 0x69,
+ 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53,
0x65, 0x72, 0x76, 0x65,
+ 0x72, 0x52, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52,
0x65, 0x71, 0x75, 0x65,
+ 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2e, 0x72,
0x65, 0x66, 0x6c, 0x65,
+ 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
0x61, 0x2e, 0x53, 0x65,
+ 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x52, 0x65,
+ 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x42, 0x4b,
0x5a, 0x49, 0x64, 0x75,
+ 0x62, 0x62, 0x6f, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x6f,
0x72, 0x67, 0x2f, 0x64,
+ 0x75, 0x62, 0x62, 0x6f, 0x2d, 0x67, 0x6f, 0x2f, 0x76, 0x33, 0x2f, 0x70,
0x72, 0x6f, 0x74, 0x6f,
+ 0x63, 0x6f, 0x6c, 0x2f, 0x74, 0x72, 0x69, 0x70, 0x6c, 0x65, 0x2f, 0x72,
0x65, 0x66, 0x6c, 0x65,
+ 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x74, 0x72, 0x69, 0x70, 0x6c, 0x65,
0x5f, 0x72, 0x65, 0x66,
+ 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x33,
+}
+
+var (
+ file_reflection_proto_rawDescOnce sync.Once
+ file_reflection_proto_rawDescData = file_reflection_proto_rawDesc
+)
+
+func file_reflection_proto_rawDescGZIP() []byte {
+ file_reflection_proto_rawDescOnce.Do(func() {
+ file_reflection_proto_rawDescData =
protoimpl.X.CompressGZIP(file_reflection_proto_rawDescData)
+ })
+ return file_reflection_proto_rawDescData
+}
+
+var file_reflection_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
+var file_reflection_proto_goTypes = []interface{}{
+ (*ServerReflectionRequest)(nil), // 0:
dubbo.reflection.v1alpha.ServerReflectionRequest
+ (*ExtensionRequest)(nil), // 1:
dubbo.reflection.v1alpha.ExtensionRequest
+ (*ServerReflectionResponse)(nil), // 2:
dubbo.reflection.v1alpha.ServerReflectionResponse
+ (*FileDescriptorResponse)(nil), // 3:
dubbo.reflection.v1alpha.FileDescriptorResponse
+ (*ExtensionNumberResponse)(nil), // 4:
dubbo.reflection.v1alpha.ExtensionNumberResponse
+ (*ListServiceResponse)(nil), // 5:
dubbo.reflection.v1alpha.ListServiceResponse
+ (*ServiceResponse)(nil), // 6:
dubbo.reflection.v1alpha.ServiceResponse
+ (*ErrorResponse)(nil), // 7:
dubbo.reflection.v1alpha.ErrorResponse
+}
+var file_reflection_proto_depIdxs = []int32{
+ 1, // 0:
dubbo.reflection.v1alpha.ServerReflectionRequest.file_containing_extension:type_name
-> dubbo.reflection.v1alpha.ExtensionRequest
+ 0, // 1:
dubbo.reflection.v1alpha.ServerReflectionResponse.original_request:type_name ->
dubbo.reflection.v1alpha.ServerReflectionRequest
+ 3, // 2:
dubbo.reflection.v1alpha.ServerReflectionResponse.file_descriptor_response:type_name
-> dubbo.reflection.v1alpha.FileDescriptorResponse
+ 4, // 3:
dubbo.reflection.v1alpha.ServerReflectionResponse.all_extension_numbers_response:type_name
-> dubbo.reflection.v1alpha.ExtensionNumberResponse
+ 5, // 4:
dubbo.reflection.v1alpha.ServerReflectionResponse.list_services_response:type_name
-> dubbo.reflection.v1alpha.ListServiceResponse
+ 7, // 5:
dubbo.reflection.v1alpha.ServerReflectionResponse.error_response:type_name ->
dubbo.reflection.v1alpha.ErrorResponse
+ 6, // 6: dubbo.reflection.v1alpha.ListServiceResponse.service:type_name
-> dubbo.reflection.v1alpha.ServiceResponse
+ 0, // 7:
dubbo.reflection.v1alpha.ServerReflection.ServerReflectionInfo:input_type ->
dubbo.reflection.v1alpha.ServerReflectionRequest
+ 2, // 8:
dubbo.reflection.v1alpha.ServerReflection.ServerReflectionInfo:output_type ->
dubbo.reflection.v1alpha.ServerReflectionResponse
+ 8, // [8:9] is the sub-list for method output_type
+ 7, // [7:8] is the sub-list for method input_type
+ 7, // [7:7] is the sub-list for extension type_name
+ 7, // [7:7] is the sub-list for extension extendee
+ 0, // [0:7] is the sub-list for field type_name
+}
+
+func init() { file_reflection_proto_init() }
+func file_reflection_proto_init() {
+ if File_reflection_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_reflection_proto_msgTypes[0].Exporter = func(v
interface{}, i int) interface{} {
+ switch v := v.(*ServerReflectionRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_reflection_proto_msgTypes[1].Exporter = func(v
interface{}, i int) interface{} {
+ switch v := v.(*ExtensionRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_reflection_proto_msgTypes[2].Exporter = func(v
interface{}, i int) interface{} {
+ switch v := v.(*ServerReflectionResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_reflection_proto_msgTypes[3].Exporter = func(v
interface{}, i int) interface{} {
+ switch v := v.(*FileDescriptorResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_reflection_proto_msgTypes[4].Exporter = func(v
interface{}, i int) interface{} {
+ switch v := v.(*ExtensionNumberResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_reflection_proto_msgTypes[5].Exporter = func(v
interface{}, i int) interface{} {
+ switch v := v.(*ListServiceResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_reflection_proto_msgTypes[6].Exporter = func(v
interface{}, i int) interface{} {
+ switch v := v.(*ServiceResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_reflection_proto_msgTypes[7].Exporter = func(v
interface{}, i int) interface{} {
+ switch v := v.(*ErrorResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ file_reflection_proto_msgTypes[0].OneofWrappers = []interface{}{
+ (*ServerReflectionRequest_FileByFilename)(nil),
+ (*ServerReflectionRequest_FileContainingSymbol)(nil),
+ (*ServerReflectionRequest_FileContainingExtension)(nil),
+ (*ServerReflectionRequest_AllExtensionNumbersOfType)(nil),
+ (*ServerReflectionRequest_ListServices)(nil),
+ }
+ file_reflection_proto_msgTypes[2].OneofWrappers = []interface{}{
+ (*ServerReflectionResponse_FileDescriptorResponse)(nil),
+ (*ServerReflectionResponse_AllExtensionNumbersResponse)(nil),
+ (*ServerReflectionResponse_ListServicesResponse)(nil),
+ (*ServerReflectionResponse_ErrorResponse)(nil),
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_reflection_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 8,
+ NumExtensions: 0,
+ NumServices: 1,
+ },
+ GoTypes: file_reflection_proto_goTypes,
+ DependencyIndexes: file_reflection_proto_depIdxs,
+ MessageInfos: file_reflection_proto_msgTypes,
+ }.Build()
+ File_reflection_proto = out.File
+ file_reflection_proto_rawDesc = nil
+ file_reflection_proto_goTypes = nil
+ file_reflection_proto_depIdxs = nil
+}
diff --git a/protocol/triple/reflection/triple_reflection/reflection.proto
b/protocol/triple/reflection/triple_reflection/reflection.proto
new file mode 100644
index 000000000..db96af2ab
--- /dev/null
+++ b/protocol/triple/reflection/triple_reflection/reflection.proto
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+// Service exported by server reflection
+
+syntax = "proto3";
+
+package dubbo.reflection.v1alpha;
+
+option go_package =
"dubbo.apache.org/dubbo-go/v3/protocol/triple/reflection/triple_reflection";
+
+service ServerReflection {
+ // The reflection service is structured as a bidirectional stream, ensuring
+ // all related requests go to a single server.
+ rpc ServerReflectionInfo(stream ServerReflectionRequest)
+ returns (stream ServerReflectionResponse);
+}
+
+// The message sent by the client when calling ServerReflectionInfo method.
+message ServerReflectionRequest {
+ string host = 1;
+ // To use reflection service, the client should set one of the following
+ // fields in message_request. The server distinguishes requests by their
+ // defined field and then handles them using corresponding methods.
+ oneof message_request {
+ // Find a proto file by the file name.
+ string file_by_filename = 3;
+
+ // Find the proto file that declares the given fully-qualified symbol name.
+ // This field should be a fully-qualified symbol name
+ // (e.g. <package>.<service>[.<method>] or <package>.<type>).
+ string file_containing_symbol = 4;
+
+ // Find the proto file which defines an extension extending the given
+ // message type with the given field number.
+ ExtensionRequest file_containing_extension = 5;
+
+ // Finds the tag numbers used by all known extensions of extendee_type, and
+ // appends them to ExtensionNumberResponse in an undefined order.
+ // Its corresponding method is best-effort: it's not guaranteed that the
+ // reflection service will implement this method, and it's not guaranteed
+ // that this method will provide all extensions. Returns
+ // StatusCode::UNIMPLEMENTED if it's not implemented.
+ // This field should be a fully-qualified type name. The format is
+ // <package>.<type>
+ string all_extension_numbers_of_type = 6;
+
+ // List the full names of registered services. The content will not be
+ // checked.
+ string list_services = 7;
+ }
+}
+
+// The type name and extension number sent by the client when requesting
+// file_containing_extension.
+message ExtensionRequest {
+ // Fully-qualified type name. The format should be <package>.<type>
+ string containing_type = 1;
+ int32 extension_number = 2;
+}
+
+// The message sent by the server to answer ServerReflectionInfo method.
+message ServerReflectionResponse {
+ string valid_host = 1;
+ ServerReflectionRequest original_request = 2;
+ // The server sets one of the following fields according to the
+ // message_request in the request.
+ oneof message_response {
+ // This message is used to answer file_by_filename, file_containing_symbol,
+ // file_containing_extension requests with transitive dependencies.
+ // As the repeated label is not allowed in oneof fields, we use a
+ // FileDescriptorResponse message to encapsulate the repeated fields.
+ // The reflection service is allowed to avoid sending FileDescriptorProtos
+ // that were previously sent in response to earlier requests in the stream.
+ FileDescriptorResponse file_descriptor_response = 4;
+
+ // This message is used to answer all_extension_numbers_of_type requests.
+ ExtensionNumberResponse all_extension_numbers_response = 5;
+
+ // This message is used to answer list_services requests.
+ ListServiceResponse list_services_response = 6;
+
+ // This message is used when an error occurs.
+ ErrorResponse error_response = 7;
+ }
+}
+
+// Serialized FileDescriptorProto messages sent by the server answering
+// a file_by_filename, file_containing_symbol, or file_containing_extension
+// request.
+message FileDescriptorResponse {
+ // Serialized FileDescriptorProto messages. We avoid taking a dependency on
+ // descriptor.proto, which uses proto2 only features, by making them opaque
+ // bytes instead.
+ repeated bytes file_descriptor_proto = 1;
+}
+
+// A list of extension numbers sent by the server answering
+// all_extension_numbers_of_type request.
+message ExtensionNumberResponse {
+ // Full name of the base type, including the package name. The format
+ // is <package>.<type>
+ string base_type_name = 1;
+ repeated int32 extension_number = 2;
+}
+
+// A list of ServiceResponse sent by the server answering list_services
request.
+message ListServiceResponse {
+ // The information of each service may be expanded in the future, so we use
+ // ServiceResponse message to encapsulate it.
+ repeated ServiceResponse service = 1;
+}
+
+// The information of a single service used by ListServiceResponse to answer
+// list_services request.
+message ServiceResponse {
+ // Full name of a registered service, including its package name. The format
+ // is <package>.<service>
+ string name = 1;
+}
+
+// The error code and error message sent by the server when an error occurs.
+message ErrorResponse {
+ // This field uses the error codes defined in grpc::StatusCode.
+ int32 error_code = 1;
+ string error_message = 2;
+}
diff --git a/protocol/triple/reflection/triple_reflection/reflection.triple.go
b/protocol/triple/reflection/triple_reflection/reflection.triple.go
new file mode 100644
index 000000000..005ab3913
--- /dev/null
+++ b/protocol/triple/reflection/triple_reflection/reflection.triple.go
@@ -0,0 +1,199 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+// Code generated by protoc-gen-triple. DO NOT EDIT.
+//
+// Source: reflection.proto
+package triple_reflection
+
+import (
+ "context"
+ "net/http"
+)
+
+import (
+ "dubbo.apache.org/dubbo-go/v3"
+ "dubbo.apache.org/dubbo-go/v3/client"
+ "dubbo.apache.org/dubbo-go/v3/common"
+ "dubbo.apache.org/dubbo-go/v3/common/constant"
+ "dubbo.apache.org/dubbo-go/v3/protocol/triple/triple_protocol"
+ "dubbo.apache.org/dubbo-go/v3/server"
+)
+
+// This is a compile-time assertion to ensure that this generated file and the
Triple package
+// are compatible. If you get a compiler error that this constant is not
defined, this code was
+// generated with a version of Triple newer than the one compiled into your
binary. You can fix the
+// problem by either regenerating this code with an older version of Triple or
updating the Triple
+// version compiled into your binary.
+const _ = triple_protocol.IsAtLeastVersion0_1_0
+
+const (
+ // ServerReflectionName is the fully-qualified name of the
ServerReflection service.
+ ServerReflectionName = "dubbo.reflection.v1alpha.ServerReflection"
+)
+
+// These constants are the fully-qualified names of the RPCs defined in this
package. They're
+// exposed at runtime as procedure and as the final two segments of the HTTP
route.
+//
+// Note that these are different from the fully-qualified method names used by
+// google.golang.org/protobuf/reflect/protoreflect. To convert from these
constants to
+// reflection-formatted method names, remove the leading slash and convert the
remaining slash to a
+// period.
+const (
+ // ServerReflectionServerReflectionInfoProcedure is the fully-qualified
name of the ServerReflection's ServerReflectionInfo RPC.
+ ServerReflectionServerReflectionInfoProcedure =
"/dubbo.reflection.v1alpha.ServerReflection/ServerReflectionInfo"
+)
+
+var (
+ _ ServerReflection = (*ServerReflectionImpl)(nil)
+
+ _ ServerReflection_ServerReflectionInfoClient =
(*ServerReflectionServerReflectionInfoClient)(nil)
+
+ _ ServerReflection_ServerReflectionInfoServer =
(*ServerReflectionServerReflectionInfoServer)(nil)
+)
+
+// ServerReflection is a client for the
dubbo.reflection.v1alpha.ServerReflection service.
+type ServerReflection interface {
+ ServerReflectionInfo(ctx context.Context, opts ...client.CallOption)
(ServerReflection_ServerReflectionInfoClient, error)
+}
+
+// NewServerReflection constructs a client for the
dubbo.reflection.v1alpha.ServerReflection service.
+func NewServerReflection(cli *client.Client, opts ...client.ReferenceOption)
(ServerReflection, error) {
+ conn, err :=
cli.DialWithInfo("dubbo.reflection.v1alpha.ServerReflection",
&ServerReflection_ClientInfo, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return &ServerReflectionImpl{
+ conn: conn,
+ }, nil
+}
+
+func SetConsumerService(srv common.RPCService) {
+ dubbo.SetConsumerServiceWithInfo(srv, &ServerReflection_ClientInfo)
+}
+
+// ServerReflectionImpl implements ServerReflection.
+type ServerReflectionImpl struct {
+ conn *client.Connection
+}
+
+func (c *ServerReflectionImpl) ServerReflectionInfo(ctx context.Context, opts
...client.CallOption) (ServerReflection_ServerReflectionInfoClient, error) {
+ stream, err := c.conn.CallBidiStream(ctx, "ServerReflectionInfo",
opts...)
+ if err != nil {
+ return nil, err
+ }
+ rawStream := stream.(*triple_protocol.BidiStreamForClient)
+ return &ServerReflectionServerReflectionInfoClient{rawStream}, nil
+}
+
+type ServerReflection_ServerReflectionInfoClient interface {
+ Spec() triple_protocol.Spec
+ Peer() triple_protocol.Peer
+ Send(*ServerReflectionRequest) error
+ RequestHeader() http.Header
+ CloseRequest() error
+ Recv() (*ServerReflectionResponse, error)
+ ResponseHeader() http.Header
+ ResponseTrailer() http.Header
+ CloseResponse() error
+}
+
+type ServerReflectionServerReflectionInfoClient struct {
+ *triple_protocol.BidiStreamForClient
+}
+
+func (cli *ServerReflectionServerReflectionInfoClient) Send(msg
*ServerReflectionRequest) error {
+ return cli.BidiStreamForClient.Send(msg)
+}
+
+func (cli *ServerReflectionServerReflectionInfoClient) Recv()
(*ServerReflectionResponse, error) {
+ msg := new(ServerReflectionResponse)
+ if err := cli.BidiStreamForClient.Receive(msg); err != nil {
+ return nil, err
+ }
+ return msg, nil
+}
+
+var ServerReflection_ClientInfo = client.ClientInfo{
+ InterfaceName: "dubbo.reflection.v1alpha.ServerReflection",
+ MethodNames: []string{"ServerReflectionInfo"},
+ ConnectionInjectFunc: func(dubboCliRaw interface{}, conn
*client.Connection) {
+ dubboCli := dubboCliRaw.(*ServerReflectionImpl)
+ dubboCli.conn = conn
+ },
+}
+
+// ServerReflectionHandler is an implementation of the
dubbo.reflection.v1alpha.ServerReflection service.
+type ServerReflectionHandler interface {
+ ServerReflectionInfo(context.Context,
ServerReflection_ServerReflectionInfoServer) error
+}
+
+func RegisterServerReflectionHandler(srv *server.Server, hdlr
ServerReflectionHandler, opts ...server.ServiceOption) error {
+ return srv.Register(hdlr, &ServerReflection_ServiceInfo, opts...)
+}
+
+func SetProviderService(srv common.RPCService) {
+ dubbo.SetProviderServiceWithInfo(srv, &ServerReflection_ServiceInfo)
+}
+
+type ServerReflection_ServerReflectionInfoServer interface {
+ Send(*ServerReflectionResponse) error
+ Recv() (*ServerReflectionRequest, error)
+ Spec() triple_protocol.Spec
+ Peer() triple_protocol.Peer
+ RequestHeader() http.Header
+ ResponseHeader() http.Header
+ ResponseTrailer() http.Header
+ Conn() triple_protocol.StreamingHandlerConn
+}
+
+type ServerReflectionServerReflectionInfoServer struct {
+ *triple_protocol.BidiStream
+}
+
+func (srv *ServerReflectionServerReflectionInfoServer) Send(msg
*ServerReflectionResponse) error {
+ return srv.BidiStream.Send(msg)
+}
+
+func (srv ServerReflectionServerReflectionInfoServer) Recv()
(*ServerReflectionRequest, error) {
+ msg := new(ServerReflectionRequest)
+ if err := srv.BidiStream.Receive(msg); err != nil {
+ return nil, err
+ }
+ return msg, nil
+}
+
+var ServerReflection_ServiceInfo = server.ServiceInfo{
+ InterfaceName: "dubbo.reflection.v1alpha.ServerReflection",
+ ServiceType: (*ServerReflectionHandler)(nil),
+ Methods: []server.MethodInfo{
+ {
+ Name: "ServerReflectionInfo",
+ Type: constant.CallBidiStream,
+ StreamInitFunc: func(baseStream interface{})
interface{} {
+ return
&ServerReflectionServerReflectionInfoServer{baseStream.(*triple_protocol.BidiStream)}
+ },
+ MethodFunc: func(ctx context.Context, args
[]interface{}, handler interface{}) (interface{}, error) {
+ stream :=
args[0].(ServerReflection_ServerReflectionInfoServer)
+ if err :=
handler.(ServerReflectionHandler).ServerReflectionInfo(ctx, stream); err != nil
{
+ return nil, err
+ }
+ return nil, nil
+ },
+ },
+ },
+}
diff --git a/protocol/triple/server.go b/protocol/triple/server.go
index b6ea60a53..847b050a0 100644
--- a/protocol/triple/server.go
+++ b/protocol/triple/server.go
@@ -33,6 +33,8 @@ import (
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
+
+ "google.golang.org/grpc"
)
import (
@@ -42,6 +44,7 @@ import (
"dubbo.apache.org/dubbo-go/v3/protocol"
"dubbo.apache.org/dubbo-go/v3/protocol/dubbo3"
"dubbo.apache.org/dubbo-go/v3/protocol/invocation"
+ "dubbo.apache.org/dubbo-go/v3/protocol/triple/reflection"
tri "dubbo.apache.org/dubbo-go/v3/protocol/triple/triple_protocol"
"dubbo.apache.org/dubbo-go/v3/server"
)
@@ -50,6 +53,8 @@ import (
type Server struct {
httpServer *http.Server
handler *http.ServeMux
+ services map[string]grpc.ServiceInfo
+ mu sync.RWMutex
}
// NewServer creates a new TRIPLE server
@@ -114,11 +119,12 @@ func (s *Server) Start(invoker protocol.Invoker, info
*server.ServiceInfo) {
mux := s.handler
if info != nil {
handleServiceWithInfo(invoker, info, mux, hanOpts...)
+ s.saveServiceInfo(info)
} else {
compatHandleService(URL, mux)
}
// todo: figure it out this process
- //reflection.Register(server)
+ reflection.Register(s)
// todo: without tls
if cfg == nil {
srv.Handler = h2c.NewHandler(mux, &http2.Server{})
@@ -150,6 +156,7 @@ func (s *Server) RefreshService(invoker protocol.Invoker,
info *server.ServiceIn
mux := s.handler
if info != nil {
handleServiceWithInfo(invoker, info, mux, hanOpts...)
+ s.saveServiceInfo(info)
} else {
compatHandleService(URL, mux)
}
@@ -339,6 +346,47 @@ func handleServiceWithInfo(invoker protocol.Invoker, info
*server.ServiceInfo, m
}
}
+func (s *Server) saveServiceInfo(info *server.ServiceInfo) {
+ ret := grpc.ServiceInfo{}
+ ret.Methods = make([]grpc.MethodInfo, 0, len(info.Methods))
+ for _, method := range info.Methods {
+ md := grpc.MethodInfo{}
+ md.Name = method.Name
+ switch method.Type {
+ case constant.CallUnary:
+ md.IsClientStream = false
+ md.IsServerStream = false
+ case constant.CallBidiStream:
+ md.IsClientStream = true
+ md.IsServerStream = true
+ case constant.CallClientStream:
+ md.IsClientStream = true
+ md.IsServerStream = false
+ case constant.CallServerStream:
+ md.IsClientStream = false
+ md.IsServerStream = true
+ }
+ ret.Methods = append(ret.Methods, md)
+ }
+ ret.Metadata = info
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ if s.services == nil {
+ s.services = make(map[string]grpc.ServiceInfo)
+ }
+ s.services[info.InterfaceName] = ret
+}
+
+func (s *Server) GetServiceInfo() map[string]grpc.ServiceInfo {
+ s.mu.RLock()
+ defer s.mu.RUnlock()
+ res := make(map[string]grpc.ServiceInfo, len(s.services))
+ for k, v := range s.services {
+ res[k] = v
+ }
+ return res
+}
+
// Stop TRIPLE server
func (s *Server) Stop() {
// todo: process error
diff --git a/protocol/triple/triple.go b/protocol/triple/triple.go
index 37217164d..de083aafc 100644
--- a/protocol/triple/triple.go
+++ b/protocol/triple/triple.go
@@ -92,6 +92,7 @@ func (tp *TripleProtocol) openServer(invoker
protocol.Invoker, info *server.Serv
tp.serverMap[url.Location].RefreshService(invoker, info)
return
}
+
if _, ok := tp.ExporterMap().Load(url.ServiceKey()); !ok {
panic("[TRIPLE Protocol]" + url.Key() + "is not existing")
}