Skip to content

Commit

Permalink
Update fetch and generate scripts for reflection (#20)
Browse files Browse the repository at this point in the history
Motivation:

To add the reflection service we need to fetch it and generate the
appropriate code.

Modifications:

- Update proto fetching script to get v1 reflection service
- Update proto generating script to generate reflection service code and
messages
- Also add protos used in tests for the reflection service and generate
their descriptor sets

Result:

Generated code is in place
  • Loading branch information
glbrntt authored Dec 20, 2024
1 parent aadf8c9 commit b7d8e22
Show file tree
Hide file tree
Showing 12 changed files with 1,345 additions and 3 deletions.
1 change: 1 addition & 0 deletions .licenseignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ dev/version-bump.commit.template
LICENSE
**/*.swift
dev/protos/**/*.proto
**/*.pb
346 changes: 346 additions & 0 deletions Sources/GRPCReflectionService/Generated/reflection.grpc.swift

Large diffs are not rendered by default.

775 changes: 775 additions & 0 deletions Sources/GRPCReflectionService/Generated/reflection.pb.swift

Large diffs are not rendered by default.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
2 changes: 2 additions & 0 deletions dev/protos/fetch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ rm -rf "$upstream"
# Create new directories to poulate. These are based on proto package name
# rather than source repository name.
mkdir -p "$upstream/grpc/health/v1"
mkdir -p "$upstream/grpc/reflection/v1"

# Copy over the grpc-proto protos.
cp -rp "$checkouts/grpc-proto/grpc/health/v1/health.proto" "$upstream/grpc/health/v1/health.proto"
cp -rp "$checkouts/grpc-proto/grpc/reflection/v1/reflection.proto" "$upstream/grpc/reflection/v1/reflection.proto"
59 changes: 56 additions & 3 deletions dev/protos/generate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,63 @@ function generate_health_service {
generate_grpc "$proto" "$(dirname "$proto")" "$output" "Visibility=Package" "Client=true" "Server=true" "UseAccessLevelOnImports=true"
}

function generate_reflection_service {
local proto="$here/upstream/grpc/reflection/v1/reflection.proto"
local output="$root/Sources/GRPCReflectionService/Generated"

generate_message "$proto" "$(dirname "$proto")" "$output" "Visibility=Package" "UseAccessLevelOnImports=true"
generate_grpc "$proto" "$(dirname "$proto")" "$output" "Visibility=Package" "UseAccessLevelOnImports=true"
}

#- TEST DATA ------------------------------------------------------------------

function generate_reflection_service_descriptor_set {
local proto="$here/upstream/grpc/reflection/v1/reflection.proto"
local proto_path="$here/upstream"
local output="$root/Tests/GRPCReflectionServiceTests/Generated/DescriptorSets/reflection.pb"

invoke_protoc --descriptor_set_out="$output" "$proto" -I "$proto_path" \
--include_source_info \
--include_imports
}

function generate_health_service_descriptor_set {
local proto="$here/upstream/grpc/health/v1/health.proto"
local proto_path="$here/upstream"
local output="$root/Tests/GRPCReflectionServiceTests/Generated/DescriptorSets/health.pb"

invoke_protoc --descriptor_set_out="$output" "$proto" -I "$proto_path" \
--include_source_info \
--include_imports
}

function generate_base_message_descriptor_set {
local proto="$here/tests/reflection/base_message.proto"
local proto_path="$here/tests/reflection"
local output="$root/Tests/GRPCReflectionServiceTests/Generated/DescriptorSets/base_message.pb"

invoke_protoc --descriptor_set_out="$output" "$proto" -I "$proto_path" \
--include_source_info \
--include_imports
}

function generate_message_with_dependency_descriptor_set {
local proto="$here/tests/reflection/message_with_dependency.proto"
local proto_path="$here/tests/reflection"
local output="$root/Tests/GRPCReflectionServiceTests/Generated/DescriptorSets/message_with_dependency.pb"

invoke_protoc --descriptor_set_out="$output" "$proto" -I "$proto_path" \
--include_source_info \
--include_imports
}

#------------------------------------------------------------------------------

# Interoperability tests
generate_interop_test_service

# Health service
generate_health_service
generate_reflection_service

generate_reflection_service_descriptor_set
generate_health_service_descriptor_set
generate_base_message_descriptor_set
generate_message_with_dependency_descriptor_set
11 changes: 11 additions & 0 deletions dev/protos/tests/reflection/base_message.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
syntax = "proto2";

message BaseMessage {
required string id = 1;

extensions 100 to 101;
}

extend BaseMessage {
optional int32 extended_field = 100;
}
7 changes: 7 additions & 0 deletions dev/protos/tests/reflection/message_with_dependency.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
syntax = "proto3";

import "google/protobuf/empty.proto";

message MessageWithDependency {
google.protobuf.Empty empty = 1;
}
147 changes: 147 additions & 0 deletions dev/protos/upstream/grpc/reflection/v1/reflection.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
// Copyright 2016 The 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.

// Service exported by server reflection. A more complete description of how
// server reflection works can be found at
// https://github.com/grpc/grpc/blob/master/doc/server-reflection.md
//
// The canonical version of this proto can be found at
// https://github.com/grpc/grpc-proto/blob/master/grpc/reflection/v1/reflection.proto

syntax = "proto3";

package grpc.reflection.v1;

option go_package = "google.golang.org/grpc/reflection/grpc_reflection_v1";
option java_multiple_files = true;
option java_package = "io.grpc.reflection.v1";
option java_outer_classname = "ServerReflectionProto";

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 the given message
// 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;
}

0 comments on commit b7d8e22

Please sign in to comment.