Merge branch 'auto-claude/002-migrate-api-routes-from-http-to-grpc'
This commit is contained in:
commit
be9ff1b7b2
@ -1,15 +1,15 @@
|
|||||||
{
|
{
|
||||||
"active": true,
|
"active": true,
|
||||||
"spec": "001-normalize-code-update-packages-widgetify-component",
|
"spec": "002-migrate-api-routes-from-http-to-grpc",
|
||||||
"state": "building",
|
"state": "building",
|
||||||
"subtasks": {
|
"subtasks": {
|
||||||
"completed": 11,
|
"completed": 10,
|
||||||
"total": 14,
|
"total": 13,
|
||||||
"in_progress": 1,
|
"in_progress": 1,
|
||||||
"failed": 0
|
"failed": 0
|
||||||
},
|
},
|
||||||
"phase": {
|
"phase": {
|
||||||
"current": "Cleanup and Verification",
|
"current": "Provider Integration",
|
||||||
"id": null,
|
"id": null,
|
||||||
"total": 3
|
"total": 3
|
||||||
},
|
},
|
||||||
@ -18,8 +18,8 @@
|
|||||||
"max": 1
|
"max": 1
|
||||||
},
|
},
|
||||||
"session": {
|
"session": {
|
||||||
"number": 12,
|
"number": 11,
|
||||||
"started_at": "2026-01-20T11:20:56.182893"
|
"started_at": "2026-01-20T12:45:59.858836"
|
||||||
},
|
},
|
||||||
"last_update": "2026-01-20T11:47:55.069999"
|
"last_update": "2026-01-20T13:09:16.962328"
|
||||||
}
|
}
|
||||||
@ -11,14 +11,14 @@
|
|||||||
"Edit(./**)",
|
"Edit(./**)",
|
||||||
"Glob(./**)",
|
"Glob(./**)",
|
||||||
"Grep(./**)",
|
"Grep(./**)",
|
||||||
"Read(/Users/mathias/Documents/workspaces/plan-b/ionic-planb-logistic-app-flutter/.auto-claude/worktrees/tasks/001-normalize-code-update-packages-widgetify-component/**)",
|
"Read(/Users/mathias/Documents/workspaces/plan-b/ionic-planb-logistic-app-flutter/.auto-claude/worktrees/tasks/002-migrate-api-routes-from-http-to-grpc/**)",
|
||||||
"Write(/Users/mathias/Documents/workspaces/plan-b/ionic-planb-logistic-app-flutter/.auto-claude/worktrees/tasks/001-normalize-code-update-packages-widgetify-component/**)",
|
"Write(/Users/mathias/Documents/workspaces/plan-b/ionic-planb-logistic-app-flutter/.auto-claude/worktrees/tasks/002-migrate-api-routes-from-http-to-grpc/**)",
|
||||||
"Edit(/Users/mathias/Documents/workspaces/plan-b/ionic-planb-logistic-app-flutter/.auto-claude/worktrees/tasks/001-normalize-code-update-packages-widgetify-component/**)",
|
"Edit(/Users/mathias/Documents/workspaces/plan-b/ionic-planb-logistic-app-flutter/.auto-claude/worktrees/tasks/002-migrate-api-routes-from-http-to-grpc/**)",
|
||||||
"Glob(/Users/mathias/Documents/workspaces/plan-b/ionic-planb-logistic-app-flutter/.auto-claude/worktrees/tasks/001-normalize-code-update-packages-widgetify-component/**)",
|
"Glob(/Users/mathias/Documents/workspaces/plan-b/ionic-planb-logistic-app-flutter/.auto-claude/worktrees/tasks/002-migrate-api-routes-from-http-to-grpc/**)",
|
||||||
"Grep(/Users/mathias/Documents/workspaces/plan-b/ionic-planb-logistic-app-flutter/.auto-claude/worktrees/tasks/001-normalize-code-update-packages-widgetify-component/**)",
|
"Grep(/Users/mathias/Documents/workspaces/plan-b/ionic-planb-logistic-app-flutter/.auto-claude/worktrees/tasks/002-migrate-api-routes-from-http-to-grpc/**)",
|
||||||
"Read(/Users/mathias/Documents/workspaces/plan-b/ionic-planb-logistic-app-flutter/.auto-claude/worktrees/tasks/001-normalize-code-update-packages-widgetify-component/.auto-claude/specs/001-normalize-code-update-packages-widgetify-component/**)",
|
"Read(/Users/mathias/Documents/workspaces/plan-b/ionic-planb-logistic-app-flutter/.auto-claude/worktrees/tasks/002-migrate-api-routes-from-http-to-grpc/.auto-claude/specs/002-migrate-api-routes-from-http-to-grpc/**)",
|
||||||
"Write(/Users/mathias/Documents/workspaces/plan-b/ionic-planb-logistic-app-flutter/.auto-claude/worktrees/tasks/001-normalize-code-update-packages-widgetify-component/.auto-claude/specs/001-normalize-code-update-packages-widgetify-component/**)",
|
"Write(/Users/mathias/Documents/workspaces/plan-b/ionic-planb-logistic-app-flutter/.auto-claude/worktrees/tasks/002-migrate-api-routes-from-http-to-grpc/.auto-claude/specs/002-migrate-api-routes-from-http-to-grpc/**)",
|
||||||
"Edit(/Users/mathias/Documents/workspaces/plan-b/ionic-planb-logistic-app-flutter/.auto-claude/worktrees/tasks/001-normalize-code-update-packages-widgetify-component/.auto-claude/specs/001-normalize-code-update-packages-widgetify-component/**)",
|
"Edit(/Users/mathias/Documents/workspaces/plan-b/ionic-planb-logistic-app-flutter/.auto-claude/worktrees/tasks/002-migrate-api-routes-from-http-to-grpc/.auto-claude/specs/002-migrate-api-routes-from-http-to-grpc/**)",
|
||||||
"Read(/Users/mathias/Documents/workspaces/plan-b/ionic-planb-logistic-app-flutter/.auto-claude/**)",
|
"Read(/Users/mathias/Documents/workspaces/plan-b/ionic-planb-logistic-app-flutter/.auto-claude/**)",
|
||||||
"Write(/Users/mathias/Documents/workspaces/plan-b/ionic-planb-logistic-app-flutter/.auto-claude/**)",
|
"Write(/Users/mathias/Documents/workspaces/plan-b/ionic-planb-logistic-app-flutter/.auto-claude/**)",
|
||||||
"Edit(/Users/mathias/Documents/workspaces/plan-b/ionic-planb-logistic-app-flutter/.auto-claude/**)",
|
"Edit(/Users/mathias/Documents/workspaces/plan-b/ionic-planb-logistic-app-flutter/.auto-claude/**)",
|
||||||
|
|||||||
550
lib/api/grpc_client.dart
Normal file
550
lib/api/grpc_client.dart
Normal file
@ -0,0 +1,550 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:grpc/grpc.dart';
|
||||||
|
|
||||||
|
import '../generated/delivery_service.pbgrpc.dart';
|
||||||
|
import '../models/delivery.dart';
|
||||||
|
import '../models/delivery_address.dart';
|
||||||
|
import '../models/delivery_contact.dart';
|
||||||
|
import '../models/delivery_order.dart';
|
||||||
|
import '../models/delivery_route.dart';
|
||||||
|
import '../models/user_info.dart';
|
||||||
|
import '../services/auth_service.dart';
|
||||||
|
import 'grpc_config.dart';
|
||||||
|
import 'types.dart';
|
||||||
|
|
||||||
|
// ignore_for_file: unused_element
|
||||||
|
|
||||||
|
/// gRPC-based CQRS API client for Plan B Logistics.
|
||||||
|
///
|
||||||
|
/// This client wraps the generated DeliveryServiceClient with `Result<T>` error
|
||||||
|
/// handling patterns consistent with [CqrsApiClient]. It provides:
|
||||||
|
/// - Lazy channel initialization
|
||||||
|
/// - Authentication via Bearer token in gRPC metadata
|
||||||
|
/// - Automatic token refresh on UNAUTHENTICATED errors
|
||||||
|
/// - Proper gRPC error to [ApiError] mapping
|
||||||
|
///
|
||||||
|
/// Usage:
|
||||||
|
/// ```dart
|
||||||
|
/// final client = GrpcCqrsApiClient(
|
||||||
|
/// config: GrpcConfig.development,
|
||||||
|
/// authService: authService,
|
||||||
|
/// );
|
||||||
|
///
|
||||||
|
/// final result = await client.getDeliveryRoutes();
|
||||||
|
/// result.when(
|
||||||
|
/// success: (routes) => handleRoutes(routes),
|
||||||
|
/// onError: (error) => handleError(error),
|
||||||
|
/// );
|
||||||
|
/// ```
|
||||||
|
class GrpcCqrsApiClient {
|
||||||
|
final GrpcConfig config;
|
||||||
|
final AuthService? authService;
|
||||||
|
|
||||||
|
ClientChannel? _channel;
|
||||||
|
DeliveryServiceClient? _deliveryClient;
|
||||||
|
|
||||||
|
GrpcCqrsApiClient({
|
||||||
|
required this.config,
|
||||||
|
this.authService,
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Returns the gRPC channel, creating it lazily if needed.
|
||||||
|
///
|
||||||
|
/// The channel is configured based on [config.useTls] for development
|
||||||
|
/// (insecure) vs production (TLS) environments.
|
||||||
|
ClientChannel get channel {
|
||||||
|
if (_channel == null) {
|
||||||
|
final credentials = config.useTls
|
||||||
|
? const ChannelCredentials.secure()
|
||||||
|
: const ChannelCredentials.insecure();
|
||||||
|
|
||||||
|
_channel = ClientChannel(
|
||||||
|
config.host,
|
||||||
|
port: config.port,
|
||||||
|
options: ChannelOptions(
|
||||||
|
credentials: credentials,
|
||||||
|
connectionTimeout: config.timeout,
|
||||||
|
idleTimeout: const Duration(minutes: 5),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return _channel!;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the DeliveryService client, creating it lazily if needed.
|
||||||
|
DeliveryServiceClient get deliveryClient {
|
||||||
|
_deliveryClient ??= DeliveryServiceClient(channel);
|
||||||
|
return _deliveryClient!;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Builds [CallOptions] with authentication metadata.
|
||||||
|
///
|
||||||
|
/// Includes Bearer token in metadata if [authService] is configured and
|
||||||
|
/// a valid token is available. Uses [AuthService.ensureValidToken] to
|
||||||
|
/// proactively refresh tokens that are expiring soon.
|
||||||
|
Future<CallOptions> _buildCallOptions() async {
|
||||||
|
final metadata = <String, String>{};
|
||||||
|
|
||||||
|
if (authService != null) {
|
||||||
|
final token = await authService!.ensureValidToken();
|
||||||
|
if (token != null) {
|
||||||
|
metadata['authorization'] = 'Bearer $token';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return CallOptions(
|
||||||
|
metadata: metadata,
|
||||||
|
timeout: config.timeout,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Merges base [CallOptions] with additional options for a specific call.
|
||||||
|
CallOptions _mergeOptions(CallOptions base, CallOptions? additional) {
|
||||||
|
if (additional == null) return base;
|
||||||
|
|
||||||
|
return CallOptions(
|
||||||
|
metadata: {
|
||||||
|
...base.metadata,
|
||||||
|
...additional.metadata,
|
||||||
|
},
|
||||||
|
timeout: additional.timeout ?? base.timeout,
|
||||||
|
providers: [
|
||||||
|
...base.metadataProviders,
|
||||||
|
...additional.metadataProviders,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Maps gRPC [GrpcError] to [ApiError] for consistent error handling.
|
||||||
|
///
|
||||||
|
/// Maps common gRPC status codes to appropriate [ApiErrorType]:
|
||||||
|
/// - UNAUTHENTICATED (16) -> HTTP 401
|
||||||
|
/// - PERMISSION_DENIED (7) -> HTTP 403
|
||||||
|
/// - NOT_FOUND (5) -> HTTP 404
|
||||||
|
/// - INVALID_ARGUMENT (3) -> Validation error
|
||||||
|
/// - DEADLINE_EXCEEDED (4) -> Timeout
|
||||||
|
/// - UNAVAILABLE (14) -> Network error
|
||||||
|
/// - Other codes -> Unknown error
|
||||||
|
ApiError _mapGrpcError(GrpcError error) {
|
||||||
|
switch (error.code) {
|
||||||
|
case StatusCode.unauthenticated:
|
||||||
|
return ApiError.http(
|
||||||
|
statusCode: 401,
|
||||||
|
message: error.message ?? 'Authentication required',
|
||||||
|
);
|
||||||
|
case StatusCode.permissionDenied:
|
||||||
|
return ApiError.http(
|
||||||
|
statusCode: 403,
|
||||||
|
message: error.message ?? 'Permission denied',
|
||||||
|
);
|
||||||
|
case StatusCode.notFound:
|
||||||
|
return ApiError.http(
|
||||||
|
statusCode: 404,
|
||||||
|
message: error.message ?? 'Resource not found',
|
||||||
|
);
|
||||||
|
case StatusCode.invalidArgument:
|
||||||
|
return ApiError.validation(
|
||||||
|
error.message ?? 'Invalid request',
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
case StatusCode.deadlineExceeded:
|
||||||
|
return ApiError.timeout();
|
||||||
|
case StatusCode.unavailable:
|
||||||
|
return ApiError.network(
|
||||||
|
error.message ?? 'Service unavailable',
|
||||||
|
);
|
||||||
|
case StatusCode.internal:
|
||||||
|
return ApiError.http(
|
||||||
|
statusCode: 500,
|
||||||
|
message: error.message ?? 'Internal server error',
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
return ApiError.unknown(
|
||||||
|
error.message ?? 'gRPC error: ${error.codeName}',
|
||||||
|
exception: error,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Executes a gRPC call with `Result<T>` error handling and authentication.
|
||||||
|
///
|
||||||
|
/// This is the core method that wraps gRPC calls with:
|
||||||
|
/// - Authentication token injection
|
||||||
|
/// - Automatic token refresh on UNAUTHENTICATED errors (single retry)
|
||||||
|
/// - gRPC error to ApiError mapping
|
||||||
|
/// - Timeout handling
|
||||||
|
///
|
||||||
|
/// [grpcCall] is the actual gRPC method invocation.
|
||||||
|
/// [isRetry] tracks whether this is a retry after token refresh.
|
||||||
|
Future<Result<T>> _executeWithAuth<T>(
|
||||||
|
Future<T> Function(CallOptions options) grpcCall, {
|
||||||
|
bool isRetry = false,
|
||||||
|
}) async {
|
||||||
|
try {
|
||||||
|
final options = await _buildCallOptions();
|
||||||
|
final result = await grpcCall(options);
|
||||||
|
return Result.success(result);
|
||||||
|
} on GrpcError catch (error) {
|
||||||
|
// Handle UNAUTHENTICATED by attempting token refresh (once)
|
||||||
|
if (error.code == StatusCode.unauthenticated &&
|
||||||
|
!isRetry &&
|
||||||
|
authService != null) {
|
||||||
|
final refreshResult = await authService!.refreshAccessToken();
|
||||||
|
return refreshResult.when(
|
||||||
|
success: (token) => _executeWithAuth(grpcCall, isRetry: true),
|
||||||
|
onError: (refreshError) => Result.error(_mapGrpcError(error)),
|
||||||
|
cancelled: () => Result.error(_mapGrpcError(error)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Result.error(_mapGrpcError(error));
|
||||||
|
} on TimeoutException {
|
||||||
|
return Result.error(ApiError.timeout());
|
||||||
|
} catch (e, stackTrace) {
|
||||||
|
return Result.error(
|
||||||
|
ApiError.unknown(
|
||||||
|
'gRPC call failed: ${e.toString()}',
|
||||||
|
exception: Exception(stackTrace.toString()),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Executes a gRPC call that returns void (for commands).
|
||||||
|
///
|
||||||
|
/// Similar to [_executeWithAuth] but for operations that don't return
|
||||||
|
/// meaningful data (commands that return success/failure).
|
||||||
|
Future<Result<void>> _executeCommandWithAuth(
|
||||||
|
Future<void> Function(CallOptions options) grpcCall, {
|
||||||
|
bool isRetry = false,
|
||||||
|
}) async {
|
||||||
|
try {
|
||||||
|
final options = await _buildCallOptions();
|
||||||
|
await grpcCall(options);
|
||||||
|
return Result.success(null);
|
||||||
|
} on GrpcError catch (error) {
|
||||||
|
if (error.code == StatusCode.unauthenticated &&
|
||||||
|
!isRetry &&
|
||||||
|
authService != null) {
|
||||||
|
final refreshResult = await authService!.refreshAccessToken();
|
||||||
|
return refreshResult.when(
|
||||||
|
success: (token) =>
|
||||||
|
_executeCommandWithAuth(grpcCall, isRetry: true),
|
||||||
|
onError: (refreshError) => Result.error(_mapGrpcError(error)),
|
||||||
|
cancelled: () => Result.error(_mapGrpcError(error)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Result.error(_mapGrpcError(error));
|
||||||
|
} on TimeoutException {
|
||||||
|
return Result.error(ApiError.timeout());
|
||||||
|
} catch (e, stackTrace) {
|
||||||
|
return Result.error(
|
||||||
|
ApiError.unknown(
|
||||||
|
'gRPC command failed: ${e.toString()}',
|
||||||
|
exception: Exception(stackTrace.toString()),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Query Methods
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
/// Gets all delivery routes.
|
||||||
|
///
|
||||||
|
/// Returns a [Result] containing a list of [DeliveryRoute] objects.
|
||||||
|
/// Maps the gRPC [DeliveryRoutesResponse] to domain models.
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
/// ```dart
|
||||||
|
/// final result = await client.getDeliveryRoutes();
|
||||||
|
/// result.when(
|
||||||
|
/// success: (routes) => displayRoutes(routes),
|
||||||
|
/// onError: (error) => showError(error.message),
|
||||||
|
/// );
|
||||||
|
/// ```
|
||||||
|
Future<Result<List<DeliveryRoute>>> getDeliveryRoutes() async {
|
||||||
|
final result = await _executeWithAuth<DeliveryRoutesResponse>(
|
||||||
|
(options) => deliveryClient.getDeliveryRoutes(Empty(), options: options),
|
||||||
|
);
|
||||||
|
|
||||||
|
return result.when(
|
||||||
|
success: (response) {
|
||||||
|
final routes = response.routes.map(_mapDeliveryRouteProto).toList();
|
||||||
|
return Result.success(routes);
|
||||||
|
},
|
||||||
|
onError: (error) => Result.error(error),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Maps a [DeliveryRouteProto] to a [DeliveryRoute] domain model.
|
||||||
|
DeliveryRoute _mapDeliveryRouteProto(DeliveryRouteProto proto) {
|
||||||
|
return DeliveryRoute(
|
||||||
|
id: proto.id,
|
||||||
|
routeId: proto.routeId,
|
||||||
|
name: proto.name,
|
||||||
|
routeName: proto.routeName,
|
||||||
|
deliveriesCount: proto.deliveriesCount,
|
||||||
|
deliveredCount: proto.deliveredCount,
|
||||||
|
completed: proto.completed,
|
||||||
|
createdAt: proto.createdAt,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets deliveries for a specific route fragment.
|
||||||
|
///
|
||||||
|
/// Returns a [Result] containing a list of [Delivery] objects for the
|
||||||
|
/// specified [routeFragmentId]. Maps the gRPC [DeliveriesResponse] to
|
||||||
|
/// domain models.
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
/// ```dart
|
||||||
|
/// final result = await client.getDeliveries(routeFragmentId: 123);
|
||||||
|
/// result.when(
|
||||||
|
/// success: (deliveries) => displayDeliveries(deliveries),
|
||||||
|
/// onError: (error) => showError(error.message),
|
||||||
|
/// );
|
||||||
|
/// ```
|
||||||
|
Future<Result<List<Delivery>>> getDeliveries({
|
||||||
|
required int routeFragmentId,
|
||||||
|
}) async {
|
||||||
|
final request = GetDeliveriesRequest(routeFragmentId: routeFragmentId);
|
||||||
|
|
||||||
|
final result = await _executeWithAuth<DeliveriesResponse>(
|
||||||
|
(options) => deliveryClient.getDeliveries(request, options: options),
|
||||||
|
);
|
||||||
|
|
||||||
|
return result.when(
|
||||||
|
success: (response) {
|
||||||
|
final deliveries =
|
||||||
|
response.deliveries.map(_mapDeliveryProto).toList();
|
||||||
|
return Result.success(deliveries);
|
||||||
|
},
|
||||||
|
onError: (error) => Result.error(error),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Maps a [DeliveryProto] to a [Delivery] domain model.
|
||||||
|
Delivery _mapDeliveryProto(DeliveryProto proto) {
|
||||||
|
return Delivery(
|
||||||
|
id: proto.id,
|
||||||
|
routeFragmentId: proto.routeFragmentId,
|
||||||
|
deliveryIndex: proto.deliveryIndex,
|
||||||
|
orders: proto.orders.map(_mapDeliveryOrderProto).toList(),
|
||||||
|
deliveredBy:
|
||||||
|
proto.hasDeliveredBy() ? _mapUserInfoProto(proto.deliveredBy) : null,
|
||||||
|
deliveryAddress: proto.hasDeliveryAddress()
|
||||||
|
? _mapDeliveryAddressProto(proto.deliveryAddress)
|
||||||
|
: null,
|
||||||
|
deliveredAt: proto.hasDeliveredAt() ? proto.deliveredAt : null,
|
||||||
|
skippedAt: proto.hasSkippedAt() ? proto.skippedAt : null,
|
||||||
|
createdAt: proto.createdAt,
|
||||||
|
updatedAt: proto.hasUpdatedAt() ? proto.updatedAt : null,
|
||||||
|
delivered: proto.delivered,
|
||||||
|
hasBeenSkipped: proto.hasBeenSkipped,
|
||||||
|
isSkipped: proto.isSkipped,
|
||||||
|
name: proto.name,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Maps a [DeliveryAddressProto] to a [DeliveryAddress] domain model.
|
||||||
|
DeliveryAddress _mapDeliveryAddressProto(DeliveryAddressProto proto) {
|
||||||
|
return DeliveryAddress(
|
||||||
|
id: proto.id,
|
||||||
|
line1: proto.hasLine1() ? proto.line1 : null,
|
||||||
|
line2: proto.hasLine2() ? proto.line2 : null,
|
||||||
|
postalCode: proto.hasPostalCode() ? proto.postalCode : null,
|
||||||
|
city: proto.hasCity() ? proto.city : null,
|
||||||
|
subdivision: proto.hasSubdivision() ? proto.subdivision : null,
|
||||||
|
countryCode: proto.hasCountryCode() ? proto.countryCode : null,
|
||||||
|
latitude: proto.hasLatitude() ? proto.latitude : null,
|
||||||
|
longitude: proto.hasLongitude() ? proto.longitude : null,
|
||||||
|
formattedAddress:
|
||||||
|
proto.hasFormattedAddress() ? proto.formattedAddress : null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Maps a [DeliveryOrderProto] to a [DeliveryOrder] domain model.
|
||||||
|
DeliveryOrder _mapDeliveryOrderProto(DeliveryOrderProto proto) {
|
||||||
|
return DeliveryOrder(
|
||||||
|
id: proto.id,
|
||||||
|
isNewCustomer: proto.isNewCustomer,
|
||||||
|
note: proto.hasNote() ? proto.note : null,
|
||||||
|
totalAmount: proto.totalAmount,
|
||||||
|
totalPaid: proto.hasTotalPaid() ? proto.totalPaid : null,
|
||||||
|
totalItems: proto.hasTotalItems() ? proto.totalItems : null,
|
||||||
|
contacts: proto.contacts.map(_mapDeliveryContactProto).toList(),
|
||||||
|
contact:
|
||||||
|
proto.hasContact() ? _mapDeliveryContactProto(proto.contact) : null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Maps a [DeliveryContactProto] to a [DeliveryContact] domain model.
|
||||||
|
DeliveryContact _mapDeliveryContactProto(DeliveryContactProto proto) {
|
||||||
|
return DeliveryContact(
|
||||||
|
firstName: proto.firstName,
|
||||||
|
lastName: proto.hasLastName() ? proto.lastName : null,
|
||||||
|
fullName: proto.fullName,
|
||||||
|
phoneNumber: proto.hasPhoneNumber() ? proto.phoneNumber : null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Maps a [UserInfoProto] to a [UserInfo] domain model.
|
||||||
|
UserInfo _mapUserInfoProto(UserInfoProto proto) {
|
||||||
|
return UserInfo(
|
||||||
|
id: proto.id,
|
||||||
|
firstName: proto.firstName,
|
||||||
|
lastName: proto.hasLastName() ? proto.lastName : null,
|
||||||
|
fullName: proto.fullName,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Command Methods
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
/// Marks a delivery as completed.
|
||||||
|
///
|
||||||
|
/// Returns a [Result] indicating success or failure. Optionally accepts
|
||||||
|
/// a [deliveredAt] timestamp; if not provided, the server will use the
|
||||||
|
/// current time.
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
/// ```dart
|
||||||
|
/// final result = await client.completeDelivery(deliveryId: 123);
|
||||||
|
/// result.when(
|
||||||
|
/// success: (_) => showSuccess('Delivery completed'),
|
||||||
|
/// onError: (error) => showError(error.message),
|
||||||
|
/// );
|
||||||
|
/// ```
|
||||||
|
Future<Result<void>> completeDelivery({
|
||||||
|
required int deliveryId,
|
||||||
|
String? deliveredAt,
|
||||||
|
}) async {
|
||||||
|
final request = CompleteDeliveryRequest(
|
||||||
|
deliveryId: deliveryId,
|
||||||
|
deliveredAt: deliveredAt,
|
||||||
|
);
|
||||||
|
|
||||||
|
final result = await _executeWithAuth<CommandResponse>(
|
||||||
|
(options) => deliveryClient.completeDelivery(request, options: options),
|
||||||
|
);
|
||||||
|
|
||||||
|
return result.when(
|
||||||
|
success: (response) {
|
||||||
|
if (response.success) {
|
||||||
|
return Result.success(null);
|
||||||
|
}
|
||||||
|
return Result.error(
|
||||||
|
ApiError.unknown(response.message.isNotEmpty
|
||||||
|
? response.message
|
||||||
|
: 'Failed to complete delivery'),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onError: (error) => Result.error(error),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Marks a delivery as uncompleted.
|
||||||
|
///
|
||||||
|
/// Returns a [Result] indicating success or failure. Use this to revert
|
||||||
|
/// a previously completed delivery back to pending status.
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
/// ```dart
|
||||||
|
/// final result = await client.markDeliveryAsUncompleted(deliveryId: 123);
|
||||||
|
/// result.when(
|
||||||
|
/// success: (_) => showSuccess('Delivery marked as uncompleted'),
|
||||||
|
/// onError: (error) => showError(error.message),
|
||||||
|
/// );
|
||||||
|
/// ```
|
||||||
|
Future<Result<void>> markDeliveryAsUncompleted({
|
||||||
|
required int deliveryId,
|
||||||
|
}) async {
|
||||||
|
final request = MarkDeliveryUncompletedRequest(
|
||||||
|
deliveryId: deliveryId,
|
||||||
|
);
|
||||||
|
|
||||||
|
final result = await _executeWithAuth<CommandResponse>(
|
||||||
|
(options) =>
|
||||||
|
deliveryClient.markDeliveryUncompleted(request, options: options),
|
||||||
|
);
|
||||||
|
|
||||||
|
return result.when(
|
||||||
|
success: (response) {
|
||||||
|
if (response.success) {
|
||||||
|
return Result.success(null);
|
||||||
|
}
|
||||||
|
return Result.error(
|
||||||
|
ApiError.unknown(response.message.isNotEmpty
|
||||||
|
? response.message
|
||||||
|
: 'Failed to mark delivery as uncompleted'),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onError: (error) => Result.error(error),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Skips a delivery.
|
||||||
|
///
|
||||||
|
/// Returns a [Result] indicating success or failure. Use this when a
|
||||||
|
/// delivery cannot be completed and needs to be skipped.
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
/// ```dart
|
||||||
|
/// final result = await client.skipDelivery(deliveryId: 123);
|
||||||
|
/// result.when(
|
||||||
|
/// success: (_) => showSuccess('Delivery skipped'),
|
||||||
|
/// onError: (error) => showError(error.message),
|
||||||
|
/// );
|
||||||
|
/// ```
|
||||||
|
Future<Result<void>> skipDelivery({
|
||||||
|
required int deliveryId,
|
||||||
|
}) async {
|
||||||
|
final request = SkipDeliveryRequest(
|
||||||
|
deliveryId: deliveryId,
|
||||||
|
);
|
||||||
|
|
||||||
|
final result = await _executeWithAuth<CommandResponse>(
|
||||||
|
(options) => deliveryClient.skipDelivery(request, options: options),
|
||||||
|
);
|
||||||
|
|
||||||
|
return result.when(
|
||||||
|
success: (response) {
|
||||||
|
if (response.success) {
|
||||||
|
return Result.success(null);
|
||||||
|
}
|
||||||
|
return Result.error(
|
||||||
|
ApiError.unknown(response.message.isNotEmpty
|
||||||
|
? response.message
|
||||||
|
: 'Failed to skip delivery'),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onError: (error) => Result.error(error),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Shuts down the gRPC channel and releases resources.
|
||||||
|
///
|
||||||
|
/// Should be called when the client is no longer needed to properly
|
||||||
|
/// clean up network resources.
|
||||||
|
Future<void> shutdown() async {
|
||||||
|
await _channel?.shutdown();
|
||||||
|
_channel = null;
|
||||||
|
_deliveryClient = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Terminates the gRPC channel immediately.
|
||||||
|
///
|
||||||
|
/// Unlike [shutdown], this does not wait for pending calls to complete.
|
||||||
|
/// Use this for emergency cleanup or when the app is terminating.
|
||||||
|
Future<void> terminate() async {
|
||||||
|
await _channel?.terminate();
|
||||||
|
_channel = null;
|
||||||
|
_deliveryClient = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the channel is currently active.
|
||||||
|
bool get isConnected => _channel != null;
|
||||||
|
}
|
||||||
59
lib/api/grpc_config.dart
Normal file
59
lib/api/grpc_config.dart
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/// Configuration for gRPC client connections.
|
||||||
|
///
|
||||||
|
/// Provides separate configurations for development and production environments
|
||||||
|
/// with appropriate security settings for each.
|
||||||
|
class GrpcConfig {
|
||||||
|
/// The gRPC server host address.
|
||||||
|
final String host;
|
||||||
|
|
||||||
|
/// The gRPC server port.
|
||||||
|
final int port;
|
||||||
|
|
||||||
|
/// Connection timeout duration.
|
||||||
|
final Duration timeout;
|
||||||
|
|
||||||
|
/// Whether to use TLS for secure connections.
|
||||||
|
///
|
||||||
|
/// When false, uses insecure (plaintext) credentials suitable only for
|
||||||
|
/// development environments.
|
||||||
|
final bool useTls;
|
||||||
|
|
||||||
|
/// Whether to allow self-signed certificates.
|
||||||
|
///
|
||||||
|
/// Only applicable when [useTls] is true. Useful for development
|
||||||
|
/// environments with self-signed certificates.
|
||||||
|
final bool allowSelfSignedCertificate;
|
||||||
|
|
||||||
|
const GrpcConfig({
|
||||||
|
required this.host,
|
||||||
|
required this.port,
|
||||||
|
this.timeout = const Duration(seconds: 30),
|
||||||
|
this.useTls = true,
|
||||||
|
this.allowSelfSignedCertificate = false,
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Development configuration pointing to local/development gRPC server.
|
||||||
|
///
|
||||||
|
/// Uses plaintext (insecure) credentials for development convenience.
|
||||||
|
static const GrpcConfig development = GrpcConfig(
|
||||||
|
host: '192.168.88.228',
|
||||||
|
port: 5011,
|
||||||
|
timeout: Duration(seconds: 30),
|
||||||
|
useTls: false,
|
||||||
|
allowSelfSignedCertificate: true,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Production configuration for the Plan B Logistics gRPC server.
|
||||||
|
///
|
||||||
|
/// Uses TLS for secure communication.
|
||||||
|
static const GrpcConfig production = GrpcConfig(
|
||||||
|
host: 'grpc-route.goutezplanb.com',
|
||||||
|
port: 443,
|
||||||
|
timeout: Duration(seconds: 30),
|
||||||
|
useTls: true,
|
||||||
|
allowSelfSignedCertificate: false,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Returns the full address string in the format "host:port".
|
||||||
|
String get address => '$host:$port';
|
||||||
|
}
|
||||||
352
lib/api/grpc_discovery.dart
Normal file
352
lib/api/grpc_discovery.dart
Normal file
@ -0,0 +1,352 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:grpc/grpc.dart';
|
||||||
|
|
||||||
|
import 'grpc_config.dart';
|
||||||
|
import '../generated/reflection.pbgrpc.dart';
|
||||||
|
import '../generated/descriptor.pb.dart';
|
||||||
|
|
||||||
|
/// Exception types for gRPC discovery operations.
|
||||||
|
abstract class GrpcDiscoveryException implements Exception {
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
GrpcDiscoveryException(this.message);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => '$runtimeType: $message';
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Thrown when the gRPC reflection service returns an error.
|
||||||
|
class ReflectionException extends GrpcDiscoveryException {
|
||||||
|
final int errorCode;
|
||||||
|
|
||||||
|
ReflectionException(super.message, this.errorCode);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'ReflectionException: $message (code: $errorCode)';
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Thrown when connection to the server fails.
|
||||||
|
class ConnectionException extends GrpcDiscoveryException {
|
||||||
|
ConnectionException(super.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents a discovered gRPC service with its methods.
|
||||||
|
class DiscoveredService {
|
||||||
|
final String name;
|
||||||
|
final List<DiscoveredMethod> methods;
|
||||||
|
|
||||||
|
const DiscoveredService({
|
||||||
|
required this.name,
|
||||||
|
required this.methods,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'DiscoveredService($name, methods: ${methods.length})';
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents a method within a discovered gRPC service.
|
||||||
|
class DiscoveredMethod {
|
||||||
|
final String name;
|
||||||
|
final String inputType;
|
||||||
|
final String outputType;
|
||||||
|
final bool clientStreaming;
|
||||||
|
final bool serverStreaming;
|
||||||
|
|
||||||
|
const DiscoveredMethod({
|
||||||
|
required this.name,
|
||||||
|
required this.inputType,
|
||||||
|
required this.outputType,
|
||||||
|
required this.clientStreaming,
|
||||||
|
required this.serverStreaming,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'DiscoveredMethod($name)';
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Client for discovering gRPC services using server reflection.
|
||||||
|
///
|
||||||
|
/// Connects to a gRPC server's reflection service to enumerate available
|
||||||
|
/// services and their method signatures. This is useful for development
|
||||||
|
/// and proto generation.
|
||||||
|
///
|
||||||
|
/// Example usage:
|
||||||
|
/// ```dart
|
||||||
|
/// final discovery = GrpcDiscoveryClient(config: GrpcConfig.development);
|
||||||
|
/// try {
|
||||||
|
/// final services = await discovery.listServices();
|
||||||
|
/// for (final service in services) {
|
||||||
|
/// print('Service: $service');
|
||||||
|
/// }
|
||||||
|
/// } finally {
|
||||||
|
/// await discovery.close();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
class GrpcDiscoveryClient {
|
||||||
|
final GrpcConfig config;
|
||||||
|
late final ClientChannel _channel;
|
||||||
|
late final ServerReflectionClient _stub;
|
||||||
|
bool _isInitialized = false;
|
||||||
|
|
||||||
|
GrpcDiscoveryClient({required this.config});
|
||||||
|
|
||||||
|
/// Initializes the gRPC channel and reflection client.
|
||||||
|
///
|
||||||
|
/// This is called automatically on first use, but can be called
|
||||||
|
/// explicitly to verify connection.
|
||||||
|
void _ensureInitialized() {
|
||||||
|
if (_isInitialized) return;
|
||||||
|
|
||||||
|
_channel = ClientChannel(
|
||||||
|
config.host,
|
||||||
|
port: config.port,
|
||||||
|
options: ChannelOptions(
|
||||||
|
credentials: config.useTls
|
||||||
|
? const ChannelCredentials.secure()
|
||||||
|
: const ChannelCredentials.insecure(),
|
||||||
|
connectionTimeout: config.timeout,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
_stub = ServerReflectionClient(_channel);
|
||||||
|
_isInitialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Lists all available services on the server.
|
||||||
|
///
|
||||||
|
/// Returns a list of fully qualified service names.
|
||||||
|
/// Excludes the reflection service itself by default.
|
||||||
|
///
|
||||||
|
/// Throws [ConnectionException] if connection fails.
|
||||||
|
/// Throws [ReflectionException] if reflection service returns an error.
|
||||||
|
Future<List<String>> listServices({bool includeReflection = false}) async {
|
||||||
|
_ensureInitialized();
|
||||||
|
|
||||||
|
try {
|
||||||
|
final responseStream = _stub.serverReflectionInfo(
|
||||||
|
_createRequestStream([
|
||||||
|
ServerReflectionRequest()..listServices = '',
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
|
final responses = await responseStream.toList();
|
||||||
|
|
||||||
|
if (responses.isEmpty) {
|
||||||
|
throw ReflectionException('No response from reflection service', 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
final response = responses.first;
|
||||||
|
if (response.hasErrorResponse()) {
|
||||||
|
throw ReflectionException(
|
||||||
|
response.errorResponse.errorMessage,
|
||||||
|
response.errorResponse.errorCode,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> services = response.listServicesResponse.service
|
||||||
|
.map((s) => s.name)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
if (!includeReflection) {
|
||||||
|
services = services
|
||||||
|
.where((s) => !s.contains('reflection'))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return services;
|
||||||
|
} on GrpcError catch (e) {
|
||||||
|
throw ConnectionException('Failed to connect to ${config.address}: ${e.message}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets file descriptors for a symbol (service, message, etc.).
|
||||||
|
///
|
||||||
|
/// Returns a list of [FileDescriptorProto] that define the symbol
|
||||||
|
/// and all its transitive dependencies.
|
||||||
|
///
|
||||||
|
/// Throws [ConnectionException] if connection fails.
|
||||||
|
/// Throws [ReflectionException] if symbol not found or other error.
|
||||||
|
Future<List<FileDescriptorProto>> getFileDescriptorsForSymbol(
|
||||||
|
String symbol,
|
||||||
|
) async {
|
||||||
|
_ensureInitialized();
|
||||||
|
|
||||||
|
try {
|
||||||
|
final responseStream = _stub.serverReflectionInfo(
|
||||||
|
_createRequestStream([
|
||||||
|
ServerReflectionRequest()..fileContainingSymbol = symbol,
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
|
final responses = await responseStream.toList();
|
||||||
|
|
||||||
|
if (responses.isEmpty) {
|
||||||
|
throw ReflectionException('No response for symbol: $symbol', 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
final response = responses.first;
|
||||||
|
if (response.hasErrorResponse()) {
|
||||||
|
throw ReflectionException(
|
||||||
|
response.errorResponse.errorMessage,
|
||||||
|
response.errorResponse.errorCode,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.fileDescriptorResponse.fileDescriptorProto
|
||||||
|
.map((bytes) => FileDescriptorProto.fromBuffer(bytes))
|
||||||
|
.toList();
|
||||||
|
} on GrpcError catch (e) {
|
||||||
|
throw ConnectionException('Failed to get descriptors: ${e.message}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets file descriptors by filename.
|
||||||
|
///
|
||||||
|
/// Returns a list of [FileDescriptorProto] for the specified file
|
||||||
|
/// and its dependencies.
|
||||||
|
///
|
||||||
|
/// Throws [ConnectionException] if connection fails.
|
||||||
|
/// Throws [ReflectionException] if file not found or other error.
|
||||||
|
Future<List<FileDescriptorProto>> getFileDescriptorsByName(
|
||||||
|
String filename,
|
||||||
|
) async {
|
||||||
|
_ensureInitialized();
|
||||||
|
|
||||||
|
try {
|
||||||
|
final responseStream = _stub.serverReflectionInfo(
|
||||||
|
_createRequestStream([
|
||||||
|
ServerReflectionRequest()..fileByFilename = filename,
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
|
final responses = await responseStream.toList();
|
||||||
|
|
||||||
|
if (responses.isEmpty) {
|
||||||
|
throw ReflectionException('No response for file: $filename', 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
final response = responses.first;
|
||||||
|
if (response.hasErrorResponse()) {
|
||||||
|
throw ReflectionException(
|
||||||
|
response.errorResponse.errorMessage,
|
||||||
|
response.errorResponse.errorCode,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.fileDescriptorResponse.fileDescriptorProto
|
||||||
|
.map((bytes) => FileDescriptorProto.fromBuffer(bytes))
|
||||||
|
.toList();
|
||||||
|
} on GrpcError catch (e) {
|
||||||
|
throw ConnectionException('Failed to get file descriptor: ${e.message}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Discovers all services and their methods.
|
||||||
|
///
|
||||||
|
/// Returns a list of [DiscoveredService] containing service names
|
||||||
|
/// and their method signatures.
|
||||||
|
///
|
||||||
|
/// This is a convenience method that combines [listServices] and
|
||||||
|
/// [getFileDescriptorsForSymbol] to provide detailed service information.
|
||||||
|
Future<List<DiscoveredService>> discoverAllServices() async {
|
||||||
|
final serviceNames = await listServices();
|
||||||
|
final List<DiscoveredService> discoveredServices = [];
|
||||||
|
|
||||||
|
for (final serviceName in serviceNames) {
|
||||||
|
try {
|
||||||
|
final descriptors = await getFileDescriptorsForSymbol(serviceName);
|
||||||
|
final methods = <DiscoveredMethod>[];
|
||||||
|
|
||||||
|
for (final descriptor in descriptors) {
|
||||||
|
for (final service in descriptor.service) {
|
||||||
|
// Match the service by fully qualified name
|
||||||
|
final fullName = descriptor.package.isEmpty
|
||||||
|
? service.name
|
||||||
|
: '${descriptor.package}.${service.name}';
|
||||||
|
|
||||||
|
if (fullName == serviceName) {
|
||||||
|
for (final method in service.method) {
|
||||||
|
methods.add(DiscoveredMethod(
|
||||||
|
name: method.name,
|
||||||
|
inputType: method.inputType,
|
||||||
|
outputType: method.outputType,
|
||||||
|
clientStreaming: method.clientStreaming,
|
||||||
|
serverStreaming: method.serverStreaming,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
discoveredServices.add(DiscoveredService(
|
||||||
|
name: serviceName,
|
||||||
|
methods: methods,
|
||||||
|
));
|
||||||
|
} on GrpcDiscoveryException {
|
||||||
|
// If we can't get details for a service, add it with no methods
|
||||||
|
discoveredServices.add(DiscoveredService(
|
||||||
|
name: serviceName,
|
||||||
|
methods: const [],
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return discoveredServices;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Discovers services matching a pattern.
|
||||||
|
///
|
||||||
|
/// Filters discovered services by name containing the [pattern].
|
||||||
|
/// Case-insensitive matching.
|
||||||
|
Future<List<DiscoveredService>> discoverServicesMatching(String pattern) async {
|
||||||
|
final services = await discoverAllServices();
|
||||||
|
final lowerPattern = pattern.toLowerCase();
|
||||||
|
return services
|
||||||
|
.where((s) => s.name.toLowerCase().contains(lowerPattern))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<ServerReflectionRequest> _createRequestStream(
|
||||||
|
List<ServerReflectionRequest> requests,
|
||||||
|
) async* {
|
||||||
|
for (final request in requests) {
|
||||||
|
yield request;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Closes the gRPC channel connection.
|
||||||
|
///
|
||||||
|
/// Should be called when done with discovery to release resources.
|
||||||
|
Future<void> close() async {
|
||||||
|
if (_isInitialized) {
|
||||||
|
await _channel.shutdown();
|
||||||
|
_isInitialized = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Utility function to discover and print gRPC services.
|
||||||
|
///
|
||||||
|
/// This is a convenience function for development and debugging.
|
||||||
|
/// Connects to the server specified in [config], discovers all services,
|
||||||
|
/// and prints them to the console.
|
||||||
|
///
|
||||||
|
/// Returns a map of service names to their discovered service details.
|
||||||
|
Future<Map<String, DiscoveredService>> discoverAndPrintServices({
|
||||||
|
GrpcConfig config = GrpcConfig.development,
|
||||||
|
}) async {
|
||||||
|
final discovery = GrpcDiscoveryClient(config: config);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final services = await discovery.discoverAllServices();
|
||||||
|
final Map<String, DiscoveredService> result = {};
|
||||||
|
|
||||||
|
for (final service in services) {
|
||||||
|
result[service.name] = service;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} finally {
|
||||||
|
await discovery.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
1351
lib/generated/delivery_service.pb.dart
Normal file
1351
lib/generated/delivery_service.pb.dart
Normal file
File diff suppressed because it is too large
Load Diff
297
lib/generated/delivery_service.pbgrpc.dart
Normal file
297
lib/generated/delivery_service.pbgrpc.dart
Normal file
@ -0,0 +1,297 @@
|
|||||||
|
// Generated code - do not modify
|
||||||
|
// ignore_for_file: annotate_overrides, camel_case_types, library_prefixes
|
||||||
|
// ignore_for_file: use_super_parameters, unused_import, non_constant_identifier_names
|
||||||
|
// Proto gRPC stubs for Plan B Logistics delivery service
|
||||||
|
|
||||||
|
import 'dart:async' as $async;
|
||||||
|
import 'dart:core' as $core;
|
||||||
|
|
||||||
|
import 'package:grpc/grpc.dart' as $grpc;
|
||||||
|
|
||||||
|
import 'delivery_service.pb.dart' as $0;
|
||||||
|
|
||||||
|
export 'delivery_service.pb.dart';
|
||||||
|
|
||||||
|
/// gRPC client for the DeliveryService.
|
||||||
|
///
|
||||||
|
/// Provides methods for querying delivery routes and deliveries,
|
||||||
|
/// as well as executing delivery commands (complete, uncomplete, skip).
|
||||||
|
class DeliveryServiceClient extends $grpc.Client {
|
||||||
|
static final _$getDeliveryRoutes =
|
||||||
|
$grpc.ClientMethod<$0.Empty, $0.DeliveryRoutesResponse>(
|
||||||
|
'/planb.delivery.DeliveryService/GetDeliveryRoutes',
|
||||||
|
($0.Empty value) => value.writeToBuffer(),
|
||||||
|
($core.List<$core.int> value) => $0.DeliveryRoutesResponse.fromBuffer(value),
|
||||||
|
);
|
||||||
|
|
||||||
|
static final _$getDeliveries =
|
||||||
|
$grpc.ClientMethod<$0.GetDeliveriesRequest, $0.DeliveriesResponse>(
|
||||||
|
'/planb.delivery.DeliveryService/GetDeliveries',
|
||||||
|
($0.GetDeliveriesRequest value) => value.writeToBuffer(),
|
||||||
|
($core.List<$core.int> value) => $0.DeliveriesResponse.fromBuffer(value),
|
||||||
|
);
|
||||||
|
|
||||||
|
static final _$completeDelivery =
|
||||||
|
$grpc.ClientMethod<$0.CompleteDeliveryRequest, $0.CommandResponse>(
|
||||||
|
'/planb.delivery.DeliveryService/CompleteDelivery',
|
||||||
|
($0.CompleteDeliveryRequest value) => value.writeToBuffer(),
|
||||||
|
($core.List<$core.int> value) => $0.CommandResponse.fromBuffer(value),
|
||||||
|
);
|
||||||
|
|
||||||
|
static final _$markDeliveryUncompleted =
|
||||||
|
$grpc.ClientMethod<$0.MarkDeliveryUncompletedRequest, $0.CommandResponse>(
|
||||||
|
'/planb.delivery.DeliveryService/MarkDeliveryUncompleted',
|
||||||
|
($0.MarkDeliveryUncompletedRequest value) => value.writeToBuffer(),
|
||||||
|
($core.List<$core.int> value) => $0.CommandResponse.fromBuffer(value),
|
||||||
|
);
|
||||||
|
|
||||||
|
static final _$skipDelivery =
|
||||||
|
$grpc.ClientMethod<$0.SkipDeliveryRequest, $0.CommandResponse>(
|
||||||
|
'/planb.delivery.DeliveryService/SkipDelivery',
|
||||||
|
($0.SkipDeliveryRequest value) => value.writeToBuffer(),
|
||||||
|
($core.List<$core.int> value) => $0.CommandResponse.fromBuffer(value),
|
||||||
|
);
|
||||||
|
|
||||||
|
static final _$uploadDeliveryPicture =
|
||||||
|
$grpc.ClientMethod<$0.UploadDeliveryPictureRequest, $0.UploadResponse>(
|
||||||
|
'/planb.delivery.DeliveryService/UploadDeliveryPicture',
|
||||||
|
($0.UploadDeliveryPictureRequest value) => value.writeToBuffer(),
|
||||||
|
($core.List<$core.int> value) => $0.UploadResponse.fromBuffer(value),
|
||||||
|
);
|
||||||
|
|
||||||
|
DeliveryServiceClient(
|
||||||
|
$grpc.ClientChannel channel, {
|
||||||
|
$grpc.CallOptions? options,
|
||||||
|
$core.Iterable<$grpc.ClientInterceptor>? interceptors,
|
||||||
|
}) : super(
|
||||||
|
channel,
|
||||||
|
options: options,
|
||||||
|
interceptors: interceptors,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Gets all delivery routes.
|
||||||
|
///
|
||||||
|
/// Returns a [DeliveryRoutesResponse] containing all available routes.
|
||||||
|
$grpc.ResponseFuture<$0.DeliveryRoutesResponse> getDeliveryRoutes(
|
||||||
|
$0.Empty request, {
|
||||||
|
$grpc.CallOptions? options,
|
||||||
|
}) {
|
||||||
|
return $createUnaryCall(
|
||||||
|
_$getDeliveryRoutes,
|
||||||
|
request,
|
||||||
|
options: options,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets deliveries for a specific route fragment.
|
||||||
|
///
|
||||||
|
/// [request] must contain the routeFragmentId.
|
||||||
|
/// Returns a [DeliveriesResponse] containing deliveries for the route.
|
||||||
|
$grpc.ResponseFuture<$0.DeliveriesResponse> getDeliveries(
|
||||||
|
$0.GetDeliveriesRequest request, {
|
||||||
|
$grpc.CallOptions? options,
|
||||||
|
}) {
|
||||||
|
return $createUnaryCall(
|
||||||
|
_$getDeliveries,
|
||||||
|
request,
|
||||||
|
options: options,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Marks a delivery as completed.
|
||||||
|
///
|
||||||
|
/// [request] must contain the deliveryId and optionally deliveredAt timestamp.
|
||||||
|
/// Returns a [CommandResponse] indicating success or failure.
|
||||||
|
$grpc.ResponseFuture<$0.CommandResponse> completeDelivery(
|
||||||
|
$0.CompleteDeliveryRequest request, {
|
||||||
|
$grpc.CallOptions? options,
|
||||||
|
}) {
|
||||||
|
return $createUnaryCall(
|
||||||
|
_$completeDelivery,
|
||||||
|
request,
|
||||||
|
options: options,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Marks a delivery as uncompleted.
|
||||||
|
///
|
||||||
|
/// [request] must contain the deliveryId.
|
||||||
|
/// Returns a [CommandResponse] indicating success or failure.
|
||||||
|
$grpc.ResponseFuture<$0.CommandResponse> markDeliveryUncompleted(
|
||||||
|
$0.MarkDeliveryUncompletedRequest request, {
|
||||||
|
$grpc.CallOptions? options,
|
||||||
|
}) {
|
||||||
|
return $createUnaryCall(
|
||||||
|
_$markDeliveryUncompleted,
|
||||||
|
request,
|
||||||
|
options: options,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Skips a delivery.
|
||||||
|
///
|
||||||
|
/// [request] must contain the deliveryId.
|
||||||
|
/// Returns a [CommandResponse] indicating success or failure.
|
||||||
|
$grpc.ResponseFuture<$0.CommandResponse> skipDelivery(
|
||||||
|
$0.SkipDeliveryRequest request, {
|
||||||
|
$grpc.CallOptions? options,
|
||||||
|
}) {
|
||||||
|
return $createUnaryCall(
|
||||||
|
_$skipDelivery,
|
||||||
|
request,
|
||||||
|
options: options,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Uploads a picture for delivery proof.
|
||||||
|
///
|
||||||
|
/// [request] must contain the deliveryId, imageData (bytes), fileName, and contentType.
|
||||||
|
/// Returns an [UploadResponse] with the uploaded URL on success.
|
||||||
|
$grpc.ResponseFuture<$0.UploadResponse> uploadDeliveryPicture(
|
||||||
|
$0.UploadDeliveryPictureRequest request, {
|
||||||
|
$grpc.CallOptions? options,
|
||||||
|
}) {
|
||||||
|
return $createUnaryCall(
|
||||||
|
_$uploadDeliveryPicture,
|
||||||
|
request,
|
||||||
|
options: options,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Server-side base class for the DeliveryService.
|
||||||
|
///
|
||||||
|
/// Implement this class to create a gRPC server for delivery operations.
|
||||||
|
abstract class DeliveryServiceBase extends $grpc.Service {
|
||||||
|
@$core.override
|
||||||
|
$core.String get $name => 'planb.delivery.DeliveryService';
|
||||||
|
|
||||||
|
DeliveryServiceBase() {
|
||||||
|
$addMethod($grpc.ServiceMethod<$0.Empty, $0.DeliveryRoutesResponse>(
|
||||||
|
'GetDeliveryRoutes',
|
||||||
|
getDeliveryRoutes_Pre,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
($core.List<$core.int> value) => $0.Empty.fromBuffer(value),
|
||||||
|
($0.DeliveryRoutesResponse value) => value.writeToBuffer(),
|
||||||
|
));
|
||||||
|
$addMethod($grpc.ServiceMethod<$0.GetDeliveriesRequest, $0.DeliveriesResponse>(
|
||||||
|
'GetDeliveries',
|
||||||
|
getDeliveries_Pre,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
($core.List<$core.int> value) => $0.GetDeliveriesRequest.fromBuffer(value),
|
||||||
|
($0.DeliveriesResponse value) => value.writeToBuffer(),
|
||||||
|
));
|
||||||
|
$addMethod($grpc.ServiceMethod<$0.CompleteDeliveryRequest, $0.CommandResponse>(
|
||||||
|
'CompleteDelivery',
|
||||||
|
completeDelivery_Pre,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
($core.List<$core.int> value) => $0.CompleteDeliveryRequest.fromBuffer(value),
|
||||||
|
($0.CommandResponse value) => value.writeToBuffer(),
|
||||||
|
));
|
||||||
|
$addMethod($grpc.ServiceMethod<$0.MarkDeliveryUncompletedRequest, $0.CommandResponse>(
|
||||||
|
'MarkDeliveryUncompleted',
|
||||||
|
markDeliveryUncompleted_Pre,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
($core.List<$core.int> value) => $0.MarkDeliveryUncompletedRequest.fromBuffer(value),
|
||||||
|
($0.CommandResponse value) => value.writeToBuffer(),
|
||||||
|
));
|
||||||
|
$addMethod($grpc.ServiceMethod<$0.SkipDeliveryRequest, $0.CommandResponse>(
|
||||||
|
'SkipDelivery',
|
||||||
|
skipDelivery_Pre,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
($core.List<$core.int> value) => $0.SkipDeliveryRequest.fromBuffer(value),
|
||||||
|
($0.CommandResponse value) => value.writeToBuffer(),
|
||||||
|
));
|
||||||
|
$addMethod($grpc.ServiceMethod<$0.UploadDeliveryPictureRequest, $0.UploadResponse>(
|
||||||
|
'UploadDeliveryPicture',
|
||||||
|
uploadDeliveryPicture_Pre,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
($core.List<$core.int> value) => $0.UploadDeliveryPictureRequest.fromBuffer(value),
|
||||||
|
($0.UploadResponse value) => value.writeToBuffer(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$async.Future<$0.DeliveryRoutesResponse> getDeliveryRoutes_Pre(
|
||||||
|
$grpc.ServiceCall call,
|
||||||
|
$async.Future<$0.Empty> request,
|
||||||
|
) async {
|
||||||
|
return getDeliveryRoutes(call, await request);
|
||||||
|
}
|
||||||
|
|
||||||
|
$async.Future<$0.DeliveriesResponse> getDeliveries_Pre(
|
||||||
|
$grpc.ServiceCall call,
|
||||||
|
$async.Future<$0.GetDeliveriesRequest> request,
|
||||||
|
) async {
|
||||||
|
return getDeliveries(call, await request);
|
||||||
|
}
|
||||||
|
|
||||||
|
$async.Future<$0.CommandResponse> completeDelivery_Pre(
|
||||||
|
$grpc.ServiceCall call,
|
||||||
|
$async.Future<$0.CompleteDeliveryRequest> request,
|
||||||
|
) async {
|
||||||
|
return completeDelivery(call, await request);
|
||||||
|
}
|
||||||
|
|
||||||
|
$async.Future<$0.CommandResponse> markDeliveryUncompleted_Pre(
|
||||||
|
$grpc.ServiceCall call,
|
||||||
|
$async.Future<$0.MarkDeliveryUncompletedRequest> request,
|
||||||
|
) async {
|
||||||
|
return markDeliveryUncompleted(call, await request);
|
||||||
|
}
|
||||||
|
|
||||||
|
$async.Future<$0.CommandResponse> skipDelivery_Pre(
|
||||||
|
$grpc.ServiceCall call,
|
||||||
|
$async.Future<$0.SkipDeliveryRequest> request,
|
||||||
|
) async {
|
||||||
|
return skipDelivery(call, await request);
|
||||||
|
}
|
||||||
|
|
||||||
|
$async.Future<$0.UploadResponse> uploadDeliveryPicture_Pre(
|
||||||
|
$grpc.ServiceCall call,
|
||||||
|
$async.Future<$0.UploadDeliveryPictureRequest> request,
|
||||||
|
) async {
|
||||||
|
return uploadDeliveryPicture(call, await request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets all delivery routes.
|
||||||
|
$async.Future<$0.DeliveryRoutesResponse> getDeliveryRoutes(
|
||||||
|
$grpc.ServiceCall call,
|
||||||
|
$0.Empty request,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Gets deliveries for a specific route fragment.
|
||||||
|
$async.Future<$0.DeliveriesResponse> getDeliveries(
|
||||||
|
$grpc.ServiceCall call,
|
||||||
|
$0.GetDeliveriesRequest request,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Marks a delivery as completed.
|
||||||
|
$async.Future<$0.CommandResponse> completeDelivery(
|
||||||
|
$grpc.ServiceCall call,
|
||||||
|
$0.CompleteDeliveryRequest request,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Marks a delivery as uncompleted.
|
||||||
|
$async.Future<$0.CommandResponse> markDeliveryUncompleted(
|
||||||
|
$grpc.ServiceCall call,
|
||||||
|
$0.MarkDeliveryUncompletedRequest request,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Skips a delivery.
|
||||||
|
$async.Future<$0.CommandResponse> skipDelivery(
|
||||||
|
$grpc.ServiceCall call,
|
||||||
|
$0.SkipDeliveryRequest request,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Uploads a picture for delivery proof.
|
||||||
|
$async.Future<$0.UploadResponse> uploadDeliveryPicture(
|
||||||
|
$grpc.ServiceCall call,
|
||||||
|
$0.UploadDeliveryPictureRequest request,
|
||||||
|
);
|
||||||
|
}
|
||||||
821
lib/generated/descriptor.pb.dart
Normal file
821
lib/generated/descriptor.pb.dart
Normal file
@ -0,0 +1,821 @@
|
|||||||
|
// Minimal FileDescriptorProto implementation for proto generation
|
||||||
|
// ignore_for_file: annotate_overrides, camel_case_types, constant_identifier_names
|
||||||
|
// ignore_for_file: non_constant_identifier_names, prefer_single_quotes, use_super_parameters
|
||||||
|
// Based on google/protobuf/descriptor.proto
|
||||||
|
|
||||||
|
import 'dart:core' as $core;
|
||||||
|
import 'package:protobuf/protobuf.dart' as $pb;
|
||||||
|
|
||||||
|
class FileDescriptorProto extends $pb.GeneratedMessage {
|
||||||
|
factory FileDescriptorProto({
|
||||||
|
$core.String? name,
|
||||||
|
$core.String? package,
|
||||||
|
$core.Iterable<$core.String>? dependency,
|
||||||
|
$core.Iterable<DescriptorProto>? messageType,
|
||||||
|
$core.Iterable<EnumDescriptorProto>? enumType,
|
||||||
|
$core.Iterable<ServiceDescriptorProto>? service,
|
||||||
|
$core.Iterable<FieldDescriptorProto>? extension,
|
||||||
|
FileOptions? options,
|
||||||
|
$core.String? syntax,
|
||||||
|
}) {
|
||||||
|
final result = create();
|
||||||
|
if (name != null) result.name = name;
|
||||||
|
if (package != null) result.package = package;
|
||||||
|
if (dependency != null) result.dependency.addAll(dependency);
|
||||||
|
if (messageType != null) result.messageType.addAll(messageType);
|
||||||
|
if (enumType != null) result.enumType.addAll(enumType);
|
||||||
|
if (service != null) result.service.addAll(service);
|
||||||
|
if (extension != null) result.extension.addAll(extension);
|
||||||
|
if (options != null) result.options = options;
|
||||||
|
if (syntax != null) result.syntax = syntax;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileDescriptorProto._() : super();
|
||||||
|
|
||||||
|
factory FileDescriptorProto.fromBuffer($core.List<$core.int> i,
|
||||||
|
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
|
||||||
|
create()..mergeFromBuffer(i, r);
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo('FileDescriptorProto',
|
||||||
|
package: const $pb.PackageName('google.protobuf'),
|
||||||
|
createEmptyInstance: create)
|
||||||
|
..aOS(1, 'name')
|
||||||
|
..aOS(2, 'package')
|
||||||
|
..pPS(3, 'dependency')
|
||||||
|
..pc<DescriptorProto>(4, 'messageType', $pb.PbFieldType.PM,
|
||||||
|
subBuilder: DescriptorProto.create)
|
||||||
|
..pc<EnumDescriptorProto>(5, 'enumType', $pb.PbFieldType.PM,
|
||||||
|
subBuilder: EnumDescriptorProto.create)
|
||||||
|
..pc<ServiceDescriptorProto>(6, 'service', $pb.PbFieldType.PM,
|
||||||
|
subBuilder: ServiceDescriptorProto.create)
|
||||||
|
..pc<FieldDescriptorProto>(7, 'extension', $pb.PbFieldType.PM,
|
||||||
|
subBuilder: FieldDescriptorProto.create)
|
||||||
|
..aOM<FileOptions>(8, 'options', subBuilder: FileOptions.create)
|
||||||
|
..aOS(12, 'syntax')
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
@$core.override
|
||||||
|
FileDescriptorProto createEmptyInstance() => create();
|
||||||
|
static FileDescriptorProto create() => FileDescriptorProto._();
|
||||||
|
@$core.override
|
||||||
|
FileDescriptorProto clone() => FileDescriptorProto()..mergeFromMessage(this);
|
||||||
|
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.String get name => $_getSZ(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
set name($core.String v) => $_setString(0, v);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.bool hasName() => $_has(0);
|
||||||
|
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
$core.String get package => $_getSZ(1);
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
set package($core.String v) => $_setString(1, v);
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
$core.bool hasPackage() => $_has(1);
|
||||||
|
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
$core.List<$core.String> get dependency => $_getList(2);
|
||||||
|
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
$core.List<DescriptorProto> get messageType => $_getList(3);
|
||||||
|
|
||||||
|
@$pb.TagNumber(5)
|
||||||
|
$core.List<EnumDescriptorProto> get enumType => $_getList(4);
|
||||||
|
|
||||||
|
@$pb.TagNumber(6)
|
||||||
|
$core.List<ServiceDescriptorProto> get service => $_getList(5);
|
||||||
|
|
||||||
|
@$pb.TagNumber(7)
|
||||||
|
$core.List<FieldDescriptorProto> get extension => $_getList(6);
|
||||||
|
|
||||||
|
@$pb.TagNumber(8)
|
||||||
|
FileOptions get options => $_getN(7);
|
||||||
|
@$pb.TagNumber(8)
|
||||||
|
set options(FileOptions v) => setField(8, v);
|
||||||
|
@$pb.TagNumber(8)
|
||||||
|
$core.bool hasOptions() => $_has(7);
|
||||||
|
@$pb.TagNumber(8)
|
||||||
|
FileOptions ensureOptions() => $_ensure(7);
|
||||||
|
|
||||||
|
@$pb.TagNumber(12)
|
||||||
|
$core.String get syntax => $_getSZ(8);
|
||||||
|
@$pb.TagNumber(12)
|
||||||
|
set syntax($core.String v) => $_setString(8, v);
|
||||||
|
@$pb.TagNumber(12)
|
||||||
|
$core.bool hasSyntax() => $_has(8);
|
||||||
|
}
|
||||||
|
|
||||||
|
class DescriptorProto extends $pb.GeneratedMessage {
|
||||||
|
factory DescriptorProto({
|
||||||
|
$core.String? name,
|
||||||
|
$core.Iterable<FieldDescriptorProto>? field,
|
||||||
|
$core.Iterable<FieldDescriptorProto>? extension,
|
||||||
|
$core.Iterable<DescriptorProto>? nestedType,
|
||||||
|
$core.Iterable<EnumDescriptorProto>? enumType,
|
||||||
|
$core.Iterable<DescriptorProto_ReservedRange>? reservedRange,
|
||||||
|
$core.Iterable<$core.String>? reservedName,
|
||||||
|
$core.Iterable<OneofDescriptorProto>? oneofDecl,
|
||||||
|
MessageOptions? options,
|
||||||
|
}) {
|
||||||
|
final result = create();
|
||||||
|
if (name != null) result.name = name;
|
||||||
|
if (field != null) result.field.addAll(field);
|
||||||
|
if (extension != null) result.extension.addAll(extension);
|
||||||
|
if (nestedType != null) result.nestedType.addAll(nestedType);
|
||||||
|
if (enumType != null) result.enumType.addAll(enumType);
|
||||||
|
if (reservedRange != null) result.reservedRange.addAll(reservedRange);
|
||||||
|
if (reservedName != null) result.reservedName.addAll(reservedName);
|
||||||
|
if (oneofDecl != null) result.oneofDecl.addAll(oneofDecl);
|
||||||
|
if (options != null) result.options = options;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DescriptorProto._() : super();
|
||||||
|
|
||||||
|
factory DescriptorProto.fromBuffer($core.List<$core.int> i,
|
||||||
|
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
|
||||||
|
create()..mergeFromBuffer(i, r);
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo('DescriptorProto',
|
||||||
|
package: const $pb.PackageName('google.protobuf'),
|
||||||
|
createEmptyInstance: create)
|
||||||
|
..aOS(1, 'name')
|
||||||
|
..pc<FieldDescriptorProto>(2, 'field', $pb.PbFieldType.PM,
|
||||||
|
subBuilder: FieldDescriptorProto.create)
|
||||||
|
..pc<FieldDescriptorProto>(6, 'extension', $pb.PbFieldType.PM,
|
||||||
|
subBuilder: FieldDescriptorProto.create)
|
||||||
|
..pc<DescriptorProto>(3, 'nestedType', $pb.PbFieldType.PM,
|
||||||
|
subBuilder: DescriptorProto.create)
|
||||||
|
..pc<EnumDescriptorProto>(4, 'enumType', $pb.PbFieldType.PM,
|
||||||
|
subBuilder: EnumDescriptorProto.create)
|
||||||
|
..pc<DescriptorProto_ReservedRange>(9, 'reservedRange', $pb.PbFieldType.PM,
|
||||||
|
subBuilder: DescriptorProto_ReservedRange.create)
|
||||||
|
..pPS(10, 'reservedName')
|
||||||
|
..pc<OneofDescriptorProto>(8, 'oneofDecl', $pb.PbFieldType.PM,
|
||||||
|
subBuilder: OneofDescriptorProto.create)
|
||||||
|
..aOM<MessageOptions>(7, 'options', subBuilder: MessageOptions.create)
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
@$core.override
|
||||||
|
DescriptorProto createEmptyInstance() => create();
|
||||||
|
static DescriptorProto create() => DescriptorProto._();
|
||||||
|
@$core.override
|
||||||
|
DescriptorProto clone() => DescriptorProto()..mergeFromMessage(this);
|
||||||
|
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.String get name => $_getSZ(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
set name($core.String v) => $_setString(0, v);
|
||||||
|
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
$core.List<FieldDescriptorProto> get field => $_getList(1);
|
||||||
|
|
||||||
|
@$pb.TagNumber(6)
|
||||||
|
$core.List<FieldDescriptorProto> get extension => $_getList(2);
|
||||||
|
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
$core.List<DescriptorProto> get nestedType => $_getList(3);
|
||||||
|
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
$core.List<EnumDescriptorProto> get enumType => $_getList(4);
|
||||||
|
|
||||||
|
@$pb.TagNumber(9)
|
||||||
|
$core.List<DescriptorProto_ReservedRange> get reservedRange => $_getList(5);
|
||||||
|
|
||||||
|
@$pb.TagNumber(10)
|
||||||
|
$core.List<$core.String> get reservedName => $_getList(6);
|
||||||
|
|
||||||
|
@$pb.TagNumber(8)
|
||||||
|
$core.List<OneofDescriptorProto> get oneofDecl => $_getList(7);
|
||||||
|
|
||||||
|
@$pb.TagNumber(7)
|
||||||
|
MessageOptions get options => $_getN(8);
|
||||||
|
@$pb.TagNumber(7)
|
||||||
|
set options(MessageOptions v) => setField(7, v);
|
||||||
|
@$pb.TagNumber(7)
|
||||||
|
$core.bool hasOptions() => $_has(8);
|
||||||
|
@$pb.TagNumber(7)
|
||||||
|
MessageOptions ensureOptions() => $_ensure(8);
|
||||||
|
}
|
||||||
|
|
||||||
|
class DescriptorProto_ReservedRange extends $pb.GeneratedMessage {
|
||||||
|
factory DescriptorProto_ReservedRange({$core.int? start, $core.int? end}) {
|
||||||
|
final result = create();
|
||||||
|
if (start != null) result.start = start;
|
||||||
|
if (end != null) result.end = end;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DescriptorProto_ReservedRange._() : super();
|
||||||
|
|
||||||
|
factory DescriptorProto_ReservedRange.fromBuffer($core.List<$core.int> i,
|
||||||
|
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
|
||||||
|
create()..mergeFromBuffer(i, r);
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo('DescriptorProto.ReservedRange',
|
||||||
|
package: const $pb.PackageName('google.protobuf'),
|
||||||
|
createEmptyInstance: create)
|
||||||
|
..a<$core.int>(1, 'start', $pb.PbFieldType.O3)
|
||||||
|
..a<$core.int>(2, 'end', $pb.PbFieldType.O3)
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
@$core.override
|
||||||
|
DescriptorProto_ReservedRange createEmptyInstance() => create();
|
||||||
|
static DescriptorProto_ReservedRange create() => DescriptorProto_ReservedRange._();
|
||||||
|
@$core.override
|
||||||
|
DescriptorProto_ReservedRange clone() => DescriptorProto_ReservedRange()..mergeFromMessage(this);
|
||||||
|
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.int get start => $_getIZ(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
set start($core.int v) => $_setSignedInt32(0, v);
|
||||||
|
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
$core.int get end => $_getIZ(1);
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
set end($core.int v) => $_setSignedInt32(1, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
class FieldDescriptorProto extends $pb.GeneratedMessage {
|
||||||
|
factory FieldDescriptorProto({
|
||||||
|
$core.String? name,
|
||||||
|
$core.int? number,
|
||||||
|
FieldDescriptorProto_Label? label,
|
||||||
|
FieldDescriptorProto_Type? type,
|
||||||
|
$core.String? typeName,
|
||||||
|
$core.String? extendee,
|
||||||
|
$core.String? defaultValue,
|
||||||
|
$core.int? oneofIndex,
|
||||||
|
$core.String? jsonName,
|
||||||
|
FieldOptions? options,
|
||||||
|
$core.bool? proto3Optional,
|
||||||
|
}) {
|
||||||
|
final result = create();
|
||||||
|
if (name != null) result.name = name;
|
||||||
|
if (number != null) result.number = number;
|
||||||
|
if (label != null) result.label = label;
|
||||||
|
if (type != null) result.type = type;
|
||||||
|
if (typeName != null) result.typeName = typeName;
|
||||||
|
if (extendee != null) result.extendee = extendee;
|
||||||
|
if (defaultValue != null) result.defaultValue = defaultValue;
|
||||||
|
if (oneofIndex != null) result.oneofIndex = oneofIndex;
|
||||||
|
if (jsonName != null) result.jsonName = jsonName;
|
||||||
|
if (options != null) result.options = options;
|
||||||
|
if (proto3Optional != null) result.proto3Optional = proto3Optional;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
FieldDescriptorProto._() : super();
|
||||||
|
|
||||||
|
factory FieldDescriptorProto.fromBuffer($core.List<$core.int> i,
|
||||||
|
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
|
||||||
|
create()..mergeFromBuffer(i, r);
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo('FieldDescriptorProto',
|
||||||
|
package: const $pb.PackageName('google.protobuf'),
|
||||||
|
createEmptyInstance: create)
|
||||||
|
..aOS(1, 'name')
|
||||||
|
..a<$core.int>(3, 'number', $pb.PbFieldType.O3)
|
||||||
|
..e<FieldDescriptorProto_Label>(4, 'label', $pb.PbFieldType.OE,
|
||||||
|
defaultOrMaker: FieldDescriptorProto_Label.LABEL_OPTIONAL,
|
||||||
|
valueOf: FieldDescriptorProto_Label.valueOf,
|
||||||
|
enumValues: FieldDescriptorProto_Label.values)
|
||||||
|
..e<FieldDescriptorProto_Type>(5, 'type', $pb.PbFieldType.OE,
|
||||||
|
defaultOrMaker: FieldDescriptorProto_Type.TYPE_DOUBLE,
|
||||||
|
valueOf: FieldDescriptorProto_Type.valueOf,
|
||||||
|
enumValues: FieldDescriptorProto_Type.values)
|
||||||
|
..aOS(6, 'typeName')
|
||||||
|
..aOS(2, 'extendee')
|
||||||
|
..aOS(7, 'defaultValue')
|
||||||
|
..a<$core.int>(9, 'oneofIndex', $pb.PbFieldType.O3)
|
||||||
|
..aOS(10, 'jsonName')
|
||||||
|
..aOM<FieldOptions>(8, 'options', subBuilder: FieldOptions.create)
|
||||||
|
..aOB(17, 'proto3Optional')
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
@$core.override
|
||||||
|
FieldDescriptorProto createEmptyInstance() => create();
|
||||||
|
static FieldDescriptorProto create() => FieldDescriptorProto._();
|
||||||
|
@$core.override
|
||||||
|
FieldDescriptorProto clone() => FieldDescriptorProto()..mergeFromMessage(this);
|
||||||
|
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.String get name => $_getSZ(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
set name($core.String v) => $_setString(0, v);
|
||||||
|
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
$core.int get number => $_getIZ(1);
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
set number($core.int v) => $_setSignedInt32(1, v);
|
||||||
|
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
FieldDescriptorProto_Label get label => $_getN(2);
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
set label(FieldDescriptorProto_Label v) => setField(4, v);
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
$core.bool hasLabel() => $_has(2);
|
||||||
|
|
||||||
|
@$pb.TagNumber(5)
|
||||||
|
FieldDescriptorProto_Type get type => $_getN(3);
|
||||||
|
@$pb.TagNumber(5)
|
||||||
|
set type(FieldDescriptorProto_Type v) => setField(5, v);
|
||||||
|
@$pb.TagNumber(5)
|
||||||
|
$core.bool hasType() => $_has(3);
|
||||||
|
|
||||||
|
@$pb.TagNumber(6)
|
||||||
|
$core.String get typeName => $_getSZ(4);
|
||||||
|
@$pb.TagNumber(6)
|
||||||
|
set typeName($core.String v) => $_setString(4, v);
|
||||||
|
@$pb.TagNumber(6)
|
||||||
|
$core.bool hasTypeName() => $_has(4);
|
||||||
|
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
$core.String get extendee => $_getSZ(5);
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
set extendee($core.String v) => $_setString(5, v);
|
||||||
|
|
||||||
|
@$pb.TagNumber(7)
|
||||||
|
$core.String get defaultValue => $_getSZ(6);
|
||||||
|
@$pb.TagNumber(7)
|
||||||
|
set defaultValue($core.String v) => $_setString(6, v);
|
||||||
|
|
||||||
|
@$pb.TagNumber(9)
|
||||||
|
$core.int get oneofIndex => $_getIZ(7);
|
||||||
|
@$pb.TagNumber(9)
|
||||||
|
set oneofIndex($core.int v) => $_setSignedInt32(7, v);
|
||||||
|
@$pb.TagNumber(9)
|
||||||
|
$core.bool hasOneofIndex() => $_has(7);
|
||||||
|
|
||||||
|
@$pb.TagNumber(10)
|
||||||
|
$core.String get jsonName => $_getSZ(8);
|
||||||
|
@$pb.TagNumber(10)
|
||||||
|
set jsonName($core.String v) => $_setString(8, v);
|
||||||
|
@$pb.TagNumber(10)
|
||||||
|
$core.bool hasJsonName() => $_has(8);
|
||||||
|
|
||||||
|
@$pb.TagNumber(8)
|
||||||
|
FieldOptions get options => $_getN(9);
|
||||||
|
@$pb.TagNumber(8)
|
||||||
|
set options(FieldOptions v) => setField(8, v);
|
||||||
|
@$pb.TagNumber(8)
|
||||||
|
$core.bool hasOptions() => $_has(9);
|
||||||
|
@$pb.TagNumber(8)
|
||||||
|
FieldOptions ensureOptions() => $_ensure(9);
|
||||||
|
|
||||||
|
@$pb.TagNumber(17)
|
||||||
|
$core.bool get proto3Optional => $_getBF(10);
|
||||||
|
@$pb.TagNumber(17)
|
||||||
|
set proto3Optional($core.bool v) => $_setBool(10, v);
|
||||||
|
@$pb.TagNumber(17)
|
||||||
|
$core.bool hasProto3Optional() => $_has(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
class FieldDescriptorProto_Type extends $pb.ProtobufEnum {
|
||||||
|
static const FieldDescriptorProto_Type TYPE_DOUBLE = FieldDescriptorProto_Type._(1, 'TYPE_DOUBLE');
|
||||||
|
static const FieldDescriptorProto_Type TYPE_FLOAT = FieldDescriptorProto_Type._(2, 'TYPE_FLOAT');
|
||||||
|
static const FieldDescriptorProto_Type TYPE_INT64 = FieldDescriptorProto_Type._(3, 'TYPE_INT64');
|
||||||
|
static const FieldDescriptorProto_Type TYPE_UINT64 = FieldDescriptorProto_Type._(4, 'TYPE_UINT64');
|
||||||
|
static const FieldDescriptorProto_Type TYPE_INT32 = FieldDescriptorProto_Type._(5, 'TYPE_INT32');
|
||||||
|
static const FieldDescriptorProto_Type TYPE_FIXED64 = FieldDescriptorProto_Type._(6, 'TYPE_FIXED64');
|
||||||
|
static const FieldDescriptorProto_Type TYPE_FIXED32 = FieldDescriptorProto_Type._(7, 'TYPE_FIXED32');
|
||||||
|
static const FieldDescriptorProto_Type TYPE_BOOL = FieldDescriptorProto_Type._(8, 'TYPE_BOOL');
|
||||||
|
static const FieldDescriptorProto_Type TYPE_STRING = FieldDescriptorProto_Type._(9, 'TYPE_STRING');
|
||||||
|
static const FieldDescriptorProto_Type TYPE_GROUP = FieldDescriptorProto_Type._(10, 'TYPE_GROUP');
|
||||||
|
static const FieldDescriptorProto_Type TYPE_MESSAGE = FieldDescriptorProto_Type._(11, 'TYPE_MESSAGE');
|
||||||
|
static const FieldDescriptorProto_Type TYPE_BYTES = FieldDescriptorProto_Type._(12, 'TYPE_BYTES');
|
||||||
|
static const FieldDescriptorProto_Type TYPE_UINT32 = FieldDescriptorProto_Type._(13, 'TYPE_UINT32');
|
||||||
|
static const FieldDescriptorProto_Type TYPE_ENUM = FieldDescriptorProto_Type._(14, 'TYPE_ENUM');
|
||||||
|
static const FieldDescriptorProto_Type TYPE_SFIXED32 = FieldDescriptorProto_Type._(15, 'TYPE_SFIXED32');
|
||||||
|
static const FieldDescriptorProto_Type TYPE_SFIXED64 = FieldDescriptorProto_Type._(16, 'TYPE_SFIXED64');
|
||||||
|
static const FieldDescriptorProto_Type TYPE_SINT32 = FieldDescriptorProto_Type._(17, 'TYPE_SINT32');
|
||||||
|
static const FieldDescriptorProto_Type TYPE_SINT64 = FieldDescriptorProto_Type._(18, 'TYPE_SINT64');
|
||||||
|
|
||||||
|
static const $core.List<FieldDescriptorProto_Type> values = [
|
||||||
|
TYPE_DOUBLE, TYPE_FLOAT, TYPE_INT64, TYPE_UINT64, TYPE_INT32,
|
||||||
|
TYPE_FIXED64, TYPE_FIXED32, TYPE_BOOL, TYPE_STRING, TYPE_GROUP,
|
||||||
|
TYPE_MESSAGE, TYPE_BYTES, TYPE_UINT32, TYPE_ENUM, TYPE_SFIXED32,
|
||||||
|
TYPE_SFIXED64, TYPE_SINT32, TYPE_SINT64,
|
||||||
|
];
|
||||||
|
|
||||||
|
static final $core.Map<$core.int, FieldDescriptorProto_Type> _byValue = $pb.ProtobufEnum.initByValue(values);
|
||||||
|
static FieldDescriptorProto_Type? valueOf($core.int value) => _byValue[value];
|
||||||
|
|
||||||
|
const FieldDescriptorProto_Type._($core.int v, $core.String n) : super(v, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
class FieldDescriptorProto_Label extends $pb.ProtobufEnum {
|
||||||
|
static const FieldDescriptorProto_Label LABEL_OPTIONAL = FieldDescriptorProto_Label._(1, 'LABEL_OPTIONAL');
|
||||||
|
static const FieldDescriptorProto_Label LABEL_REQUIRED = FieldDescriptorProto_Label._(2, 'LABEL_REQUIRED');
|
||||||
|
static const FieldDescriptorProto_Label LABEL_REPEATED = FieldDescriptorProto_Label._(3, 'LABEL_REPEATED');
|
||||||
|
|
||||||
|
static const $core.List<FieldDescriptorProto_Label> values = [LABEL_OPTIONAL, LABEL_REQUIRED, LABEL_REPEATED];
|
||||||
|
|
||||||
|
static final $core.Map<$core.int, FieldDescriptorProto_Label> _byValue = $pb.ProtobufEnum.initByValue(values);
|
||||||
|
static FieldDescriptorProto_Label? valueOf($core.int value) => _byValue[value];
|
||||||
|
|
||||||
|
const FieldDescriptorProto_Label._($core.int v, $core.String n) : super(v, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
class EnumDescriptorProto extends $pb.GeneratedMessage {
|
||||||
|
factory EnumDescriptorProto({
|
||||||
|
$core.String? name,
|
||||||
|
$core.Iterable<EnumValueDescriptorProto>? value,
|
||||||
|
EnumOptions? options,
|
||||||
|
}) {
|
||||||
|
final result = create();
|
||||||
|
if (name != null) result.name = name;
|
||||||
|
if (value != null) result.value.addAll(value);
|
||||||
|
if (options != null) result.options = options;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnumDescriptorProto._() : super();
|
||||||
|
|
||||||
|
factory EnumDescriptorProto.fromBuffer($core.List<$core.int> i,
|
||||||
|
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
|
||||||
|
create()..mergeFromBuffer(i, r);
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo('EnumDescriptorProto',
|
||||||
|
package: const $pb.PackageName('google.protobuf'),
|
||||||
|
createEmptyInstance: create)
|
||||||
|
..aOS(1, 'name')
|
||||||
|
..pc<EnumValueDescriptorProto>(2, 'value', $pb.PbFieldType.PM,
|
||||||
|
subBuilder: EnumValueDescriptorProto.create)
|
||||||
|
..aOM<EnumOptions>(3, 'options', subBuilder: EnumOptions.create)
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
@$core.override
|
||||||
|
EnumDescriptorProto createEmptyInstance() => create();
|
||||||
|
static EnumDescriptorProto create() => EnumDescriptorProto._();
|
||||||
|
@$core.override
|
||||||
|
EnumDescriptorProto clone() => EnumDescriptorProto()..mergeFromMessage(this);
|
||||||
|
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.String get name => $_getSZ(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
set name($core.String v) => $_setString(0, v);
|
||||||
|
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
$core.List<EnumValueDescriptorProto> get value => $_getList(1);
|
||||||
|
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
EnumOptions get options => $_getN(2);
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
set options(EnumOptions v) => setField(3, v);
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
$core.bool hasOptions() => $_has(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
class EnumValueDescriptorProto extends $pb.GeneratedMessage {
|
||||||
|
factory EnumValueDescriptorProto({$core.String? name, $core.int? number}) {
|
||||||
|
final result = create();
|
||||||
|
if (name != null) result.name = name;
|
||||||
|
if (number != null) result.number = number;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnumValueDescriptorProto._() : super();
|
||||||
|
|
||||||
|
factory EnumValueDescriptorProto.fromBuffer($core.List<$core.int> i,
|
||||||
|
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
|
||||||
|
create()..mergeFromBuffer(i, r);
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo('EnumValueDescriptorProto',
|
||||||
|
package: const $pb.PackageName('google.protobuf'),
|
||||||
|
createEmptyInstance: create)
|
||||||
|
..aOS(1, 'name')
|
||||||
|
..a<$core.int>(2, 'number', $pb.PbFieldType.O3)
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
@$core.override
|
||||||
|
EnumValueDescriptorProto createEmptyInstance() => create();
|
||||||
|
static EnumValueDescriptorProto create() => EnumValueDescriptorProto._();
|
||||||
|
@$core.override
|
||||||
|
EnumValueDescriptorProto clone() => EnumValueDescriptorProto()..mergeFromMessage(this);
|
||||||
|
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.String get name => $_getSZ(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
set name($core.String v) => $_setString(0, v);
|
||||||
|
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
$core.int get number => $_getIZ(1);
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
set number($core.int v) => $_setSignedInt32(1, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ServiceDescriptorProto extends $pb.GeneratedMessage {
|
||||||
|
factory ServiceDescriptorProto({
|
||||||
|
$core.String? name,
|
||||||
|
$core.Iterable<MethodDescriptorProto>? method,
|
||||||
|
ServiceOptions? options,
|
||||||
|
}) {
|
||||||
|
final result = create();
|
||||||
|
if (name != null) result.name = name;
|
||||||
|
if (method != null) result.method.addAll(method);
|
||||||
|
if (options != null) result.options = options;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServiceDescriptorProto._() : super();
|
||||||
|
|
||||||
|
factory ServiceDescriptorProto.fromBuffer($core.List<$core.int> i,
|
||||||
|
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
|
||||||
|
create()..mergeFromBuffer(i, r);
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo('ServiceDescriptorProto',
|
||||||
|
package: const $pb.PackageName('google.protobuf'),
|
||||||
|
createEmptyInstance: create)
|
||||||
|
..aOS(1, 'name')
|
||||||
|
..pc<MethodDescriptorProto>(2, 'method', $pb.PbFieldType.PM,
|
||||||
|
subBuilder: MethodDescriptorProto.create)
|
||||||
|
..aOM<ServiceOptions>(3, 'options', subBuilder: ServiceOptions.create)
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
@$core.override
|
||||||
|
ServiceDescriptorProto createEmptyInstance() => create();
|
||||||
|
static ServiceDescriptorProto create() => ServiceDescriptorProto._();
|
||||||
|
@$core.override
|
||||||
|
ServiceDescriptorProto clone() => ServiceDescriptorProto()..mergeFromMessage(this);
|
||||||
|
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.String get name => $_getSZ(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
set name($core.String v) => $_setString(0, v);
|
||||||
|
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
$core.List<MethodDescriptorProto> get method => $_getList(1);
|
||||||
|
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
ServiceOptions get options => $_getN(2);
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
set options(ServiceOptions v) => setField(3, v);
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
$core.bool hasOptions() => $_has(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
class MethodDescriptorProto extends $pb.GeneratedMessage {
|
||||||
|
factory MethodDescriptorProto({
|
||||||
|
$core.String? name,
|
||||||
|
$core.String? inputType,
|
||||||
|
$core.String? outputType,
|
||||||
|
MethodOptions? options,
|
||||||
|
$core.bool? clientStreaming,
|
||||||
|
$core.bool? serverStreaming,
|
||||||
|
}) {
|
||||||
|
final result = create();
|
||||||
|
if (name != null) result.name = name;
|
||||||
|
if (inputType != null) result.inputType = inputType;
|
||||||
|
if (outputType != null) result.outputType = outputType;
|
||||||
|
if (options != null) result.options = options;
|
||||||
|
if (clientStreaming != null) result.clientStreaming = clientStreaming;
|
||||||
|
if (serverStreaming != null) result.serverStreaming = serverStreaming;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
MethodDescriptorProto._() : super();
|
||||||
|
|
||||||
|
factory MethodDescriptorProto.fromBuffer($core.List<$core.int> i,
|
||||||
|
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
|
||||||
|
create()..mergeFromBuffer(i, r);
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo('MethodDescriptorProto',
|
||||||
|
package: const $pb.PackageName('google.protobuf'),
|
||||||
|
createEmptyInstance: create)
|
||||||
|
..aOS(1, 'name')
|
||||||
|
..aOS(2, 'inputType')
|
||||||
|
..aOS(3, 'outputType')
|
||||||
|
..aOM<MethodOptions>(4, 'options', subBuilder: MethodOptions.create)
|
||||||
|
..aOB(5, 'clientStreaming')
|
||||||
|
..aOB(6, 'serverStreaming')
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
@$core.override
|
||||||
|
MethodDescriptorProto createEmptyInstance() => create();
|
||||||
|
static MethodDescriptorProto create() => MethodDescriptorProto._();
|
||||||
|
@$core.override
|
||||||
|
MethodDescriptorProto clone() => MethodDescriptorProto()..mergeFromMessage(this);
|
||||||
|
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.String get name => $_getSZ(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
set name($core.String v) => $_setString(0, v);
|
||||||
|
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
$core.String get inputType => $_getSZ(1);
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
set inputType($core.String v) => $_setString(1, v);
|
||||||
|
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
$core.String get outputType => $_getSZ(2);
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
set outputType($core.String v) => $_setString(2, v);
|
||||||
|
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
MethodOptions get options => $_getN(3);
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
set options(MethodOptions v) => setField(4, v);
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
$core.bool hasOptions() => $_has(3);
|
||||||
|
|
||||||
|
@$pb.TagNumber(5)
|
||||||
|
$core.bool get clientStreaming => $_getBF(4);
|
||||||
|
@$pb.TagNumber(5)
|
||||||
|
set clientStreaming($core.bool v) => $_setBool(4, v);
|
||||||
|
|
||||||
|
@$pb.TagNumber(6)
|
||||||
|
$core.bool get serverStreaming => $_getBF(5);
|
||||||
|
@$pb.TagNumber(6)
|
||||||
|
set serverStreaming($core.bool v) => $_setBool(5, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
class OneofDescriptorProto extends $pb.GeneratedMessage {
|
||||||
|
factory OneofDescriptorProto({$core.String? name}) {
|
||||||
|
final result = create();
|
||||||
|
if (name != null) result.name = name;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
OneofDescriptorProto._() : super();
|
||||||
|
|
||||||
|
factory OneofDescriptorProto.fromBuffer($core.List<$core.int> i,
|
||||||
|
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
|
||||||
|
create()..mergeFromBuffer(i, r);
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo('OneofDescriptorProto',
|
||||||
|
package: const $pb.PackageName('google.protobuf'),
|
||||||
|
createEmptyInstance: create)
|
||||||
|
..aOS(1, 'name')
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
@$core.override
|
||||||
|
OneofDescriptorProto createEmptyInstance() => create();
|
||||||
|
static OneofDescriptorProto create() => OneofDescriptorProto._();
|
||||||
|
@$core.override
|
||||||
|
OneofDescriptorProto clone() => OneofDescriptorProto()..mergeFromMessage(this);
|
||||||
|
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.String get name => $_getSZ(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
set name($core.String v) => $_setString(0, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Options classes - minimal implementations
|
||||||
|
class FileOptions extends $pb.GeneratedMessage {
|
||||||
|
FileOptions._() : super();
|
||||||
|
|
||||||
|
factory FileOptions.fromBuffer($core.List<$core.int> i,
|
||||||
|
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
|
||||||
|
create()..mergeFromBuffer(i, r);
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo('FileOptions',
|
||||||
|
package: const $pb.PackageName('google.protobuf'),
|
||||||
|
createEmptyInstance: create)
|
||||||
|
..aOS(1, 'javaPackage')
|
||||||
|
..aOS(8, 'javaOuterClassname')
|
||||||
|
..aOB(10, 'javaMultipleFiles')
|
||||||
|
..aOS(11, 'goPackage')
|
||||||
|
..aOS(37, 'csharpNamespace')
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
@$core.override
|
||||||
|
FileOptions createEmptyInstance() => create();
|
||||||
|
static FileOptions create() => FileOptions._();
|
||||||
|
@$core.override
|
||||||
|
FileOptions clone() => create()..mergeFromMessage(this);
|
||||||
|
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.String get javaPackage => $_getSZ(0);
|
||||||
|
@$pb.TagNumber(8)
|
||||||
|
$core.String get javaOuterClassname => $_getSZ(1);
|
||||||
|
@$pb.TagNumber(10)
|
||||||
|
$core.bool get javaMultipleFiles => $_getBF(2);
|
||||||
|
@$pb.TagNumber(11)
|
||||||
|
$core.String get goPackage => $_getSZ(3);
|
||||||
|
@$pb.TagNumber(37)
|
||||||
|
$core.String get csharpNamespace => $_getSZ(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
class MessageOptions extends $pb.GeneratedMessage {
|
||||||
|
MessageOptions._() : super();
|
||||||
|
|
||||||
|
factory MessageOptions.fromBuffer($core.List<$core.int> i,
|
||||||
|
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
|
||||||
|
create()..mergeFromBuffer(i, r);
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo('MessageOptions',
|
||||||
|
package: const $pb.PackageName('google.protobuf'),
|
||||||
|
createEmptyInstance: create)
|
||||||
|
..aOB(7, 'mapEntry')
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
@$core.override
|
||||||
|
MessageOptions createEmptyInstance() => create();
|
||||||
|
static MessageOptions create() => MessageOptions._();
|
||||||
|
@$core.override
|
||||||
|
MessageOptions clone() => create()..mergeFromMessage(this);
|
||||||
|
|
||||||
|
@$pb.TagNumber(7)
|
||||||
|
$core.bool get mapEntry => $_getBF(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
class FieldOptions extends $pb.GeneratedMessage {
|
||||||
|
FieldOptions._() : super();
|
||||||
|
|
||||||
|
factory FieldOptions.fromBuffer($core.List<$core.int> i,
|
||||||
|
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
|
||||||
|
create()..mergeFromBuffer(i, r);
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo('FieldOptions',
|
||||||
|
package: const $pb.PackageName('google.protobuf'),
|
||||||
|
createEmptyInstance: create)
|
||||||
|
..aOB(2, 'packed')
|
||||||
|
..aOB(3, 'deprecated')
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
@$core.override
|
||||||
|
FieldOptions createEmptyInstance() => create();
|
||||||
|
static FieldOptions create() => FieldOptions._();
|
||||||
|
@$core.override
|
||||||
|
FieldOptions clone() => create()..mergeFromMessage(this);
|
||||||
|
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
$core.bool get packed => $_getBF(0);
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
$core.bool get deprecated => $_getBF(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
class EnumOptions extends $pb.GeneratedMessage {
|
||||||
|
EnumOptions._() : super();
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo('EnumOptions',
|
||||||
|
package: const $pb.PackageName('google.protobuf'),
|
||||||
|
createEmptyInstance: create)
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
@$core.override
|
||||||
|
EnumOptions createEmptyInstance() => create();
|
||||||
|
static EnumOptions create() => EnumOptions._();
|
||||||
|
@$core.override
|
||||||
|
EnumOptions clone() => create()..mergeFromMessage(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ServiceOptions extends $pb.GeneratedMessage {
|
||||||
|
ServiceOptions._() : super();
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo('ServiceOptions',
|
||||||
|
package: const $pb.PackageName('google.protobuf'),
|
||||||
|
createEmptyInstance: create)
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
@$core.override
|
||||||
|
ServiceOptions createEmptyInstance() => create();
|
||||||
|
static ServiceOptions create() => ServiceOptions._();
|
||||||
|
@$core.override
|
||||||
|
ServiceOptions clone() => create()..mergeFromMessage(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
class MethodOptions extends $pb.GeneratedMessage {
|
||||||
|
MethodOptions._() : super();
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo('MethodOptions',
|
||||||
|
package: const $pb.PackageName('google.protobuf'),
|
||||||
|
createEmptyInstance: create)
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
@$core.override
|
||||||
|
MethodOptions createEmptyInstance() => create();
|
||||||
|
static MethodOptions create() => MethodOptions._();
|
||||||
|
@$core.override
|
||||||
|
MethodOptions clone() => create()..mergeFromMessage(this);
|
||||||
|
}
|
||||||
571
lib/generated/reflection.pb.dart
Normal file
571
lib/generated/reflection.pb.dart
Normal file
@ -0,0 +1,571 @@
|
|||||||
|
// Generated code - do not modify
|
||||||
|
// ignore_for_file: annotate_overrides, camel_case_types, constant_identifier_names
|
||||||
|
// ignore_for_file: non_constant_identifier_names, avoid_print
|
||||||
|
// Based on grpc.reflection.v1alpha.reflection.proto
|
||||||
|
|
||||||
|
import 'dart:core' as $core;
|
||||||
|
import 'package:protobuf/protobuf.dart' as $pb;
|
||||||
|
|
||||||
|
enum ServerReflectionRequest_MessageRequest {
|
||||||
|
fileByFilename,
|
||||||
|
fileContainingSymbol,
|
||||||
|
fileContainingExtension,
|
||||||
|
allExtensionNumbersOfType,
|
||||||
|
listServices,
|
||||||
|
notSet
|
||||||
|
}
|
||||||
|
|
||||||
|
class ServerReflectionRequest extends $pb.GeneratedMessage {
|
||||||
|
factory ServerReflectionRequest({
|
||||||
|
$core.String? host,
|
||||||
|
$core.String? fileByFilename,
|
||||||
|
$core.String? fileContainingSymbol,
|
||||||
|
ExtensionRequest? fileContainingExtension,
|
||||||
|
$core.String? allExtensionNumbersOfType,
|
||||||
|
$core.String? listServices,
|
||||||
|
}) {
|
||||||
|
final result = create();
|
||||||
|
if (host != null) result.host = host;
|
||||||
|
if (fileByFilename != null) result.fileByFilename = fileByFilename;
|
||||||
|
if (fileContainingSymbol != null) result.fileContainingSymbol = fileContainingSymbol;
|
||||||
|
if (fileContainingExtension != null) result.fileContainingExtension = fileContainingExtension;
|
||||||
|
if (allExtensionNumbersOfType != null) result.allExtensionNumbersOfType = allExtensionNumbersOfType;
|
||||||
|
if (listServices != null) result.listServices = listServices;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerReflectionRequest._() : super();
|
||||||
|
|
||||||
|
factory ServerReflectionRequest.fromBuffer($core.List<$core.int> i,
|
||||||
|
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
|
||||||
|
create()..mergeFromBuffer(i, r);
|
||||||
|
|
||||||
|
factory ServerReflectionRequest.fromJson($core.String i,
|
||||||
|
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
|
||||||
|
create()..mergeFromJson(i, r);
|
||||||
|
|
||||||
|
static const $core.Map<$core.int, ServerReflectionRequest_MessageRequest>
|
||||||
|
_ServerReflectionRequest_MessageRequestByTag = {
|
||||||
|
3: ServerReflectionRequest_MessageRequest.fileByFilename,
|
||||||
|
4: ServerReflectionRequest_MessageRequest.fileContainingSymbol,
|
||||||
|
5: ServerReflectionRequest_MessageRequest.fileContainingExtension,
|
||||||
|
6: ServerReflectionRequest_MessageRequest.allExtensionNumbersOfType,
|
||||||
|
7: ServerReflectionRequest_MessageRequest.listServices,
|
||||||
|
0: ServerReflectionRequest_MessageRequest.notSet
|
||||||
|
};
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo(
|
||||||
|
'ServerReflectionRequest',
|
||||||
|
package: const $pb.PackageName('grpc.reflection.v1alpha'),
|
||||||
|
createEmptyInstance: create)
|
||||||
|
..oo(0, [3, 4, 5, 6, 7])
|
||||||
|
..aOS(1, 'host')
|
||||||
|
..aOS(3, 'fileByFilename')
|
||||||
|
..aOS(4, 'fileContainingSymbol')
|
||||||
|
..aOM<ExtensionRequest>(5, 'fileContainingExtension',
|
||||||
|
subBuilder: ExtensionRequest.create)
|
||||||
|
..aOS(6, 'allExtensionNumbersOfType')
|
||||||
|
..aOS(7, 'listServices')
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
ServerReflectionRequest createEmptyInstance() => create();
|
||||||
|
|
||||||
|
static ServerReflectionRequest create() => ServerReflectionRequest._();
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
ServerReflectionRequest clone() => ServerReflectionRequest()..mergeFromMessage(this);
|
||||||
|
|
||||||
|
static $core.List<ServerReflectionRequest> createRepeated() => <ServerReflectionRequest>[];
|
||||||
|
|
||||||
|
ServerReflectionRequest_MessageRequest whichMessageRequest() =>
|
||||||
|
_ServerReflectionRequest_MessageRequestByTag[$_whichOneof(0)] ??
|
||||||
|
ServerReflectionRequest_MessageRequest.notSet;
|
||||||
|
|
||||||
|
void clearMessageRequest() => clearField($_whichOneof(0));
|
||||||
|
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.String get host => $_getSZ(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
set host($core.String v) => $_setString(0, v);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.bool hasHost() => $_has(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
void clearHost() => clearField(1);
|
||||||
|
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
$core.String get fileByFilename => $_getSZ(1);
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
set fileByFilename($core.String v) => $_setString(1, v);
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
$core.bool hasFileByFilename() => $_has(1);
|
||||||
|
@$pb.TagNumber(3)
|
||||||
|
void clearFileByFilename() => clearField(3);
|
||||||
|
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
$core.String get fileContainingSymbol => $_getSZ(2);
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
set fileContainingSymbol($core.String v) => $_setString(2, v);
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
$core.bool hasFileContainingSymbol() => $_has(2);
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
void clearFileContainingSymbol() => clearField(4);
|
||||||
|
|
||||||
|
@$pb.TagNumber(5)
|
||||||
|
ExtensionRequest get fileContainingExtension => $_getN(3);
|
||||||
|
@$pb.TagNumber(5)
|
||||||
|
set fileContainingExtension(ExtensionRequest v) => setField(5, v);
|
||||||
|
@$pb.TagNumber(5)
|
||||||
|
$core.bool hasFileContainingExtension() => $_has(3);
|
||||||
|
@$pb.TagNumber(5)
|
||||||
|
void clearFileContainingExtension() => clearField(5);
|
||||||
|
@$pb.TagNumber(5)
|
||||||
|
ExtensionRequest ensureFileContainingExtension() => $_ensure(3);
|
||||||
|
|
||||||
|
@$pb.TagNumber(6)
|
||||||
|
$core.String get allExtensionNumbersOfType => $_getSZ(4);
|
||||||
|
@$pb.TagNumber(6)
|
||||||
|
set allExtensionNumbersOfType($core.String v) => $_setString(4, v);
|
||||||
|
@$pb.TagNumber(6)
|
||||||
|
$core.bool hasAllExtensionNumbersOfType() => $_has(4);
|
||||||
|
@$pb.TagNumber(6)
|
||||||
|
void clearAllExtensionNumbersOfType() => clearField(6);
|
||||||
|
|
||||||
|
@$pb.TagNumber(7)
|
||||||
|
$core.String get listServices => $_getSZ(5);
|
||||||
|
@$pb.TagNumber(7)
|
||||||
|
set listServices($core.String v) => $_setString(5, v);
|
||||||
|
@$pb.TagNumber(7)
|
||||||
|
$core.bool hasListServices() => $_has(5);
|
||||||
|
@$pb.TagNumber(7)
|
||||||
|
void clearListServices() => clearField(7);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ExtensionRequest extends $pb.GeneratedMessage {
|
||||||
|
factory ExtensionRequest({
|
||||||
|
$core.String? containingType,
|
||||||
|
$core.int? extensionNumber,
|
||||||
|
}) {
|
||||||
|
final result = create();
|
||||||
|
if (containingType != null) result.containingType = containingType;
|
||||||
|
if (extensionNumber != null) result.extensionNumber = extensionNumber;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtensionRequest._() : super();
|
||||||
|
|
||||||
|
factory ExtensionRequest.fromBuffer($core.List<$core.int> i,
|
||||||
|
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
|
||||||
|
create()..mergeFromBuffer(i, r);
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo('ExtensionRequest',
|
||||||
|
package: const $pb.PackageName('grpc.reflection.v1alpha'),
|
||||||
|
createEmptyInstance: create)
|
||||||
|
..aOS(1, 'containingType')
|
||||||
|
..a<$core.int>(2, 'extensionNumber', $pb.PbFieldType.O3)
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
ExtensionRequest createEmptyInstance() => create();
|
||||||
|
|
||||||
|
static ExtensionRequest create() => ExtensionRequest._();
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
ExtensionRequest clone() => ExtensionRequest()..mergeFromMessage(this);
|
||||||
|
|
||||||
|
static $core.List<ExtensionRequest> createRepeated() => <ExtensionRequest>[];
|
||||||
|
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.String get containingType => $_getSZ(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
set containingType($core.String v) => $_setString(0, v);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.bool hasContainingType() => $_has(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
void clearContainingType() => clearField(1);
|
||||||
|
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
$core.int get extensionNumber => $_getIZ(1);
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
set extensionNumber($core.int v) => $_setSignedInt32(1, v);
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
$core.bool hasExtensionNumber() => $_has(1);
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
void clearExtensionNumber() => clearField(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ServerReflectionResponse_MessageResponse {
|
||||||
|
fileDescriptorResponse,
|
||||||
|
allExtensionNumbersResponse,
|
||||||
|
listServicesResponse,
|
||||||
|
errorResponse,
|
||||||
|
notSet
|
||||||
|
}
|
||||||
|
|
||||||
|
class ServerReflectionResponse extends $pb.GeneratedMessage {
|
||||||
|
factory ServerReflectionResponse({
|
||||||
|
$core.String? validHost,
|
||||||
|
ServerReflectionRequest? originalRequest,
|
||||||
|
FileDescriptorResponse? fileDescriptorResponse,
|
||||||
|
ExtensionNumberResponse? allExtensionNumbersResponse,
|
||||||
|
ListServiceResponse? listServicesResponse,
|
||||||
|
ErrorResponse? errorResponse,
|
||||||
|
}) {
|
||||||
|
final result = create();
|
||||||
|
if (validHost != null) result.validHost = validHost;
|
||||||
|
if (originalRequest != null) result.originalRequest = originalRequest;
|
||||||
|
if (fileDescriptorResponse != null) result.fileDescriptorResponse = fileDescriptorResponse;
|
||||||
|
if (allExtensionNumbersResponse != null) result.allExtensionNumbersResponse = allExtensionNumbersResponse;
|
||||||
|
if (listServicesResponse != null) result.listServicesResponse = listServicesResponse;
|
||||||
|
if (errorResponse != null) result.errorResponse = errorResponse;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerReflectionResponse._() : super();
|
||||||
|
|
||||||
|
factory ServerReflectionResponse.fromBuffer($core.List<$core.int> i,
|
||||||
|
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
|
||||||
|
create()..mergeFromBuffer(i, r);
|
||||||
|
|
||||||
|
static const $core.Map<$core.int, ServerReflectionResponse_MessageResponse>
|
||||||
|
_ServerReflectionResponse_MessageResponseByTag = {
|
||||||
|
4: ServerReflectionResponse_MessageResponse.fileDescriptorResponse,
|
||||||
|
5: ServerReflectionResponse_MessageResponse.allExtensionNumbersResponse,
|
||||||
|
6: ServerReflectionResponse_MessageResponse.listServicesResponse,
|
||||||
|
7: ServerReflectionResponse_MessageResponse.errorResponse,
|
||||||
|
0: ServerReflectionResponse_MessageResponse.notSet
|
||||||
|
};
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo(
|
||||||
|
'ServerReflectionResponse',
|
||||||
|
package: const $pb.PackageName('grpc.reflection.v1alpha'),
|
||||||
|
createEmptyInstance: create)
|
||||||
|
..oo(0, [4, 5, 6, 7])
|
||||||
|
..aOS(1, 'validHost')
|
||||||
|
..aOM<ServerReflectionRequest>(2, 'originalRequest',
|
||||||
|
subBuilder: ServerReflectionRequest.create)
|
||||||
|
..aOM<FileDescriptorResponse>(4, 'fileDescriptorResponse',
|
||||||
|
subBuilder: FileDescriptorResponse.create)
|
||||||
|
..aOM<ExtensionNumberResponse>(5, 'allExtensionNumbersResponse',
|
||||||
|
subBuilder: ExtensionNumberResponse.create)
|
||||||
|
..aOM<ListServiceResponse>(6, 'listServicesResponse',
|
||||||
|
subBuilder: ListServiceResponse.create)
|
||||||
|
..aOM<ErrorResponse>(7, 'errorResponse', subBuilder: ErrorResponse.create)
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
ServerReflectionResponse createEmptyInstance() => create();
|
||||||
|
|
||||||
|
static ServerReflectionResponse create() => ServerReflectionResponse._();
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
ServerReflectionResponse clone() => ServerReflectionResponse()..mergeFromMessage(this);
|
||||||
|
|
||||||
|
static $core.List<ServerReflectionResponse> createRepeated() => <ServerReflectionResponse>[];
|
||||||
|
|
||||||
|
ServerReflectionResponse_MessageResponse whichMessageResponse() =>
|
||||||
|
_ServerReflectionResponse_MessageResponseByTag[$_whichOneof(0)] ??
|
||||||
|
ServerReflectionResponse_MessageResponse.notSet;
|
||||||
|
|
||||||
|
void clearMessageResponse() => clearField($_whichOneof(0));
|
||||||
|
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.String get validHost => $_getSZ(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
set validHost($core.String v) => $_setString(0, v);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.bool hasValidHost() => $_has(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
void clearValidHost() => clearField(1);
|
||||||
|
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
ServerReflectionRequest get originalRequest => $_getN(1);
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
set originalRequest(ServerReflectionRequest v) => setField(2, v);
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
$core.bool hasOriginalRequest() => $_has(1);
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
void clearOriginalRequest() => clearField(2);
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
ServerReflectionRequest ensureOriginalRequest() => $_ensure(1);
|
||||||
|
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
FileDescriptorResponse get fileDescriptorResponse => $_getN(2);
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
set fileDescriptorResponse(FileDescriptorResponse v) => setField(4, v);
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
$core.bool hasFileDescriptorResponse() => $_has(2);
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
void clearFileDescriptorResponse() => clearField(4);
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
FileDescriptorResponse ensureFileDescriptorResponse() => $_ensure(2);
|
||||||
|
|
||||||
|
@$pb.TagNumber(5)
|
||||||
|
ExtensionNumberResponse get allExtensionNumbersResponse => $_getN(3);
|
||||||
|
@$pb.TagNumber(5)
|
||||||
|
set allExtensionNumbersResponse(ExtensionNumberResponse v) => setField(5, v);
|
||||||
|
@$pb.TagNumber(5)
|
||||||
|
$core.bool hasAllExtensionNumbersResponse() => $_has(3);
|
||||||
|
@$pb.TagNumber(5)
|
||||||
|
void clearAllExtensionNumbersResponse() => clearField(5);
|
||||||
|
@$pb.TagNumber(5)
|
||||||
|
ExtensionNumberResponse ensureAllExtensionNumbersResponse() => $_ensure(3);
|
||||||
|
|
||||||
|
@$pb.TagNumber(6)
|
||||||
|
ListServiceResponse get listServicesResponse => $_getN(4);
|
||||||
|
@$pb.TagNumber(6)
|
||||||
|
set listServicesResponse(ListServiceResponse v) => setField(6, v);
|
||||||
|
@$pb.TagNumber(6)
|
||||||
|
$core.bool hasListServicesResponse() => $_has(4);
|
||||||
|
@$pb.TagNumber(6)
|
||||||
|
void clearListServicesResponse() => clearField(6);
|
||||||
|
@$pb.TagNumber(6)
|
||||||
|
ListServiceResponse ensureListServicesResponse() => $_ensure(4);
|
||||||
|
|
||||||
|
@$pb.TagNumber(7)
|
||||||
|
ErrorResponse get errorResponse => $_getN(5);
|
||||||
|
@$pb.TagNumber(7)
|
||||||
|
set errorResponse(ErrorResponse v) => setField(7, v);
|
||||||
|
@$pb.TagNumber(7)
|
||||||
|
$core.bool hasErrorResponse() => $_has(5);
|
||||||
|
@$pb.TagNumber(7)
|
||||||
|
void clearErrorResponse() => clearField(7);
|
||||||
|
@$pb.TagNumber(7)
|
||||||
|
ErrorResponse ensureErrorResponse() => $_ensure(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
class FileDescriptorResponse extends $pb.GeneratedMessage {
|
||||||
|
factory FileDescriptorResponse({
|
||||||
|
$core.Iterable<$core.List<$core.int>>? fileDescriptorProto,
|
||||||
|
}) {
|
||||||
|
final result = create();
|
||||||
|
if (fileDescriptorProto != null) result.fileDescriptorProto.addAll(fileDescriptorProto);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileDescriptorResponse._() : super();
|
||||||
|
|
||||||
|
factory FileDescriptorResponse.fromBuffer($core.List<$core.int> i,
|
||||||
|
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
|
||||||
|
create()..mergeFromBuffer(i, r);
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo('FileDescriptorResponse',
|
||||||
|
package: const $pb.PackageName('grpc.reflection.v1alpha'),
|
||||||
|
createEmptyInstance: create)
|
||||||
|
..p<$core.List<$core.int>>(1, 'fileDescriptorProto', $pb.PbFieldType.PY)
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
FileDescriptorResponse createEmptyInstance() => create();
|
||||||
|
|
||||||
|
static FileDescriptorResponse create() => FileDescriptorResponse._();
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
FileDescriptorResponse clone() => FileDescriptorResponse()..mergeFromMessage(this);
|
||||||
|
|
||||||
|
static $core.List<FileDescriptorResponse> createRepeated() => <FileDescriptorResponse>[];
|
||||||
|
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.List<$core.List<$core.int>> get fileDescriptorProto => $_getList(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ExtensionNumberResponse extends $pb.GeneratedMessage {
|
||||||
|
factory ExtensionNumberResponse({
|
||||||
|
$core.String? baseTypeName,
|
||||||
|
$core.Iterable<$core.int>? extensionNumber,
|
||||||
|
}) {
|
||||||
|
final result = create();
|
||||||
|
if (baseTypeName != null) result.baseTypeName = baseTypeName;
|
||||||
|
if (extensionNumber != null) result.extensionNumber.addAll(extensionNumber);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtensionNumberResponse._() : super();
|
||||||
|
|
||||||
|
factory ExtensionNumberResponse.fromBuffer($core.List<$core.int> i,
|
||||||
|
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
|
||||||
|
create()..mergeFromBuffer(i, r);
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo('ExtensionNumberResponse',
|
||||||
|
package: const $pb.PackageName('grpc.reflection.v1alpha'),
|
||||||
|
createEmptyInstance: create)
|
||||||
|
..aOS(1, 'baseTypeName')
|
||||||
|
..p<$core.int>(2, 'extensionNumber', $pb.PbFieldType.P3)
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
ExtensionNumberResponse createEmptyInstance() => create();
|
||||||
|
|
||||||
|
static ExtensionNumberResponse create() => ExtensionNumberResponse._();
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
ExtensionNumberResponse clone() => ExtensionNumberResponse()..mergeFromMessage(this);
|
||||||
|
|
||||||
|
static $core.List<ExtensionNumberResponse> createRepeated() => <ExtensionNumberResponse>[];
|
||||||
|
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.String get baseTypeName => $_getSZ(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
set baseTypeName($core.String v) => $_setString(0, v);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.bool hasBaseTypeName() => $_has(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
void clearBaseTypeName() => clearField(1);
|
||||||
|
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
$core.List<$core.int> get extensionNumber => $_getList(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ListServiceResponse extends $pb.GeneratedMessage {
|
||||||
|
factory ListServiceResponse({
|
||||||
|
$core.Iterable<ServiceResponse>? service,
|
||||||
|
}) {
|
||||||
|
final result = create();
|
||||||
|
if (service != null) result.service.addAll(service);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ListServiceResponse._() : super();
|
||||||
|
|
||||||
|
factory ListServiceResponse.fromBuffer($core.List<$core.int> i,
|
||||||
|
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
|
||||||
|
create()..mergeFromBuffer(i, r);
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo('ListServiceResponse',
|
||||||
|
package: const $pb.PackageName('grpc.reflection.v1alpha'),
|
||||||
|
createEmptyInstance: create)
|
||||||
|
..pc<ServiceResponse>(1, 'service', $pb.PbFieldType.PM,
|
||||||
|
subBuilder: ServiceResponse.create)
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
ListServiceResponse createEmptyInstance() => create();
|
||||||
|
|
||||||
|
static ListServiceResponse create() => ListServiceResponse._();
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
ListServiceResponse clone() => ListServiceResponse()..mergeFromMessage(this);
|
||||||
|
|
||||||
|
static $core.List<ListServiceResponse> createRepeated() => <ListServiceResponse>[];
|
||||||
|
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.List<ServiceResponse> get service => $_getList(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ServiceResponse extends $pb.GeneratedMessage {
|
||||||
|
factory ServiceResponse({
|
||||||
|
$core.String? name,
|
||||||
|
}) {
|
||||||
|
final result = create();
|
||||||
|
if (name != null) result.name = name;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServiceResponse._() : super();
|
||||||
|
|
||||||
|
factory ServiceResponse.fromBuffer($core.List<$core.int> i,
|
||||||
|
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
|
||||||
|
create()..mergeFromBuffer(i, r);
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo('ServiceResponse',
|
||||||
|
package: const $pb.PackageName('grpc.reflection.v1alpha'),
|
||||||
|
createEmptyInstance: create)
|
||||||
|
..aOS(1, 'name')
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
ServiceResponse createEmptyInstance() => create();
|
||||||
|
|
||||||
|
static ServiceResponse create() => ServiceResponse._();
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
ServiceResponse clone() => ServiceResponse()..mergeFromMessage(this);
|
||||||
|
|
||||||
|
static $core.List<ServiceResponse> createRepeated() => <ServiceResponse>[];
|
||||||
|
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.String get name => $_getSZ(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
set name($core.String v) => $_setString(0, v);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.bool hasName() => $_has(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
void clearName() => clearField(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ErrorResponse extends $pb.GeneratedMessage {
|
||||||
|
factory ErrorResponse({
|
||||||
|
$core.int? errorCode,
|
||||||
|
$core.String? errorMessage,
|
||||||
|
}) {
|
||||||
|
final result = create();
|
||||||
|
if (errorCode != null) result.errorCode = errorCode;
|
||||||
|
if (errorMessage != null) result.errorMessage = errorMessage;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorResponse._() : super();
|
||||||
|
|
||||||
|
factory ErrorResponse.fromBuffer($core.List<$core.int> i,
|
||||||
|
[$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
|
||||||
|
create()..mergeFromBuffer(i, r);
|
||||||
|
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo('ErrorResponse',
|
||||||
|
package: const $pb.PackageName('grpc.reflection.v1alpha'),
|
||||||
|
createEmptyInstance: create)
|
||||||
|
..a<$core.int>(1, 'errorCode', $pb.PbFieldType.O3)
|
||||||
|
..aOS(2, 'errorMessage')
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
ErrorResponse createEmptyInstance() => create();
|
||||||
|
|
||||||
|
static ErrorResponse create() => ErrorResponse._();
|
||||||
|
|
||||||
|
@$core.override
|
||||||
|
ErrorResponse clone() => ErrorResponse()..mergeFromMessage(this);
|
||||||
|
|
||||||
|
static $core.List<ErrorResponse> createRepeated() => <ErrorResponse>[];
|
||||||
|
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.int get errorCode => $_getIZ(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
set errorCode($core.int v) => $_setSignedInt32(0, v);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.bool hasErrorCode() => $_has(0);
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
void clearErrorCode() => clearField(1);
|
||||||
|
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
$core.String get errorMessage => $_getSZ(1);
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
set errorMessage($core.String v) => $_setString(1, v);
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
$core.bool hasErrorMessage() => $_has(1);
|
||||||
|
@$pb.TagNumber(2)
|
||||||
|
void clearErrorMessage() => clearField(2);
|
||||||
|
}
|
||||||
64
lib/generated/reflection.pbgrpc.dart
Normal file
64
lib/generated/reflection.pbgrpc.dart
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// Generated code - do not modify
|
||||||
|
// ignore_for_file: annotate_overrides, camel_case_types, library_prefixes
|
||||||
|
// ignore_for_file: use_super_parameters, unused_import
|
||||||
|
// Based on grpc.reflection.v1alpha.reflection.proto
|
||||||
|
|
||||||
|
import 'dart:async' as $async;
|
||||||
|
import 'dart:core' as $core;
|
||||||
|
|
||||||
|
import 'package:grpc/grpc.dart' as $grpc;
|
||||||
|
|
||||||
|
import 'reflection.pb.dart' as $0;
|
||||||
|
|
||||||
|
export 'reflection.pb.dart';
|
||||||
|
|
||||||
|
class ServerReflectionClient extends $grpc.Client {
|
||||||
|
static final _$serverReflectionInfo =
|
||||||
|
$grpc.ClientMethod<$0.ServerReflectionRequest, $0.ServerReflectionResponse>(
|
||||||
|
'/grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo',
|
||||||
|
($0.ServerReflectionRequest value) => value.writeToBuffer(),
|
||||||
|
($core.List<$core.int> value) => $0.ServerReflectionResponse.fromBuffer(value),
|
||||||
|
);
|
||||||
|
|
||||||
|
ServerReflectionClient(
|
||||||
|
$grpc.ClientChannel channel, {
|
||||||
|
$grpc.CallOptions? options,
|
||||||
|
$core.Iterable<$grpc.ClientInterceptor>? interceptors,
|
||||||
|
}) : super(
|
||||||
|
channel,
|
||||||
|
options: options,
|
||||||
|
interceptors: interceptors,
|
||||||
|
);
|
||||||
|
|
||||||
|
$grpc.ResponseStream<$0.ServerReflectionResponse> serverReflectionInfo(
|
||||||
|
$async.Stream<$0.ServerReflectionRequest> request, {
|
||||||
|
$grpc.CallOptions? options,
|
||||||
|
}) {
|
||||||
|
return $createStreamingCall(
|
||||||
|
_$serverReflectionInfo,
|
||||||
|
request,
|
||||||
|
options: options,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class ServerReflectionServiceBase extends $grpc.Service {
|
||||||
|
@$core.override
|
||||||
|
$core.String get $name => 'grpc.reflection.v1alpha.ServerReflection';
|
||||||
|
|
||||||
|
ServerReflectionServiceBase() {
|
||||||
|
$addMethod($grpc.ServiceMethod<$0.ServerReflectionRequest, $0.ServerReflectionResponse>(
|
||||||
|
'ServerReflectionInfo',
|
||||||
|
serverReflectionInfo,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
($core.List<$core.int> value) => $0.ServerReflectionRequest.fromBuffer(value),
|
||||||
|
($0.ServerReflectionResponse value) => value.writeToBuffer(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$async.Stream<$0.ServerReflectionResponse> serverReflectionInfo(
|
||||||
|
$grpc.ServiceCall call,
|
||||||
|
$async.Stream<$0.ServerReflectionRequest> request,
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -3,12 +3,108 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import '../api/types.dart';
|
import '../api/types.dart';
|
||||||
import '../api/client.dart';
|
import '../api/client.dart';
|
||||||
|
import '../api/grpc_client.dart';
|
||||||
|
import '../api/grpc_config.dart';
|
||||||
import '../api/openapi_config.dart';
|
import '../api/openapi_config.dart';
|
||||||
import '../services/auth_service.dart';
|
import '../services/auth_service.dart';
|
||||||
import '../models/user_profile.dart';
|
import '../models/user_profile.dart';
|
||||||
import '../models/delivery_route.dart';
|
import '../models/delivery_route.dart';
|
||||||
import '../models/delivery.dart';
|
import '../models/delivery.dart';
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// API Mode Configuration - Feature Flag for HTTP/gRPC Transport
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
/// Enum representing the available API transport modes.
|
||||||
|
enum ApiMode {
|
||||||
|
/// Use HTTP/REST-based CQRS API client
|
||||||
|
http,
|
||||||
|
|
||||||
|
/// Use gRPC-based CQRS API client
|
||||||
|
grpc,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configuration for API transport mode selection.
|
||||||
|
///
|
||||||
|
/// This class allows switching between HTTP and gRPC transports
|
||||||
|
/// for API calls. Following the pattern from [ApiClientConfig].
|
||||||
|
///
|
||||||
|
/// Example usage:
|
||||||
|
/// ```dart
|
||||||
|
/// // To switch to gRPC, override the apiModeConfigProvider:
|
||||||
|
/// ProviderScope(
|
||||||
|
/// overrides: [
|
||||||
|
/// apiModeConfigProvider.overrideWithValue(ApiModeConfig.developmentGrpc),
|
||||||
|
/// ],
|
||||||
|
/// child: MyApp(),
|
||||||
|
/// )
|
||||||
|
/// ```
|
||||||
|
class ApiModeConfig {
|
||||||
|
/// The transport mode to use for API calls.
|
||||||
|
final ApiMode mode;
|
||||||
|
|
||||||
|
/// Whether to fall back to HTTP on gRPC failures.
|
||||||
|
/// Only applicable when [mode] is [ApiMode.grpc].
|
||||||
|
final bool fallbackToHttpOnError;
|
||||||
|
|
||||||
|
const ApiModeConfig({
|
||||||
|
required this.mode,
|
||||||
|
this.fallbackToHttpOnError = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Development configuration - defaults to HTTP for stability.
|
||||||
|
/// Use this for safe development when gRPC backend may be unavailable.
|
||||||
|
static const ApiModeConfig development = ApiModeConfig(
|
||||||
|
mode: ApiMode.http,
|
||||||
|
fallbackToHttpOnError: true,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// gRPC-first development configuration for testing gRPC integration.
|
||||||
|
/// Use this when actively developing/testing gRPC functionality.
|
||||||
|
static const ApiModeConfig developmentGrpc = ApiModeConfig(
|
||||||
|
mode: ApiMode.grpc,
|
||||||
|
fallbackToHttpOnError: true,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Production configuration - uses HTTP until gRPC is verified stable.
|
||||||
|
static const ApiModeConfig production = ApiModeConfig(
|
||||||
|
mode: ApiMode.http,
|
||||||
|
fallbackToHttpOnError: false,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Production gRPC configuration for when gRPC is production-ready.
|
||||||
|
static const ApiModeConfig productionGrpc = ApiModeConfig(
|
||||||
|
mode: ApiMode.grpc,
|
||||||
|
fallbackToHttpOnError: false,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Whether the current mode is gRPC.
|
||||||
|
bool get isGrpc => mode == ApiMode.grpc;
|
||||||
|
|
||||||
|
/// Whether the current mode is HTTP.
|
||||||
|
bool get isHttp => mode == ApiMode.http;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Provider for API mode configuration.
|
||||||
|
///
|
||||||
|
/// Override this provider to switch between HTTP and gRPC:
|
||||||
|
/// ```dart
|
||||||
|
/// ProviderScope(
|
||||||
|
/// overrides: [
|
||||||
|
/// apiModeConfigProvider.overrideWithValue(ApiModeConfig.developmentGrpc),
|
||||||
|
/// ],
|
||||||
|
/// child: MyApp(),
|
||||||
|
/// )
|
||||||
|
/// ```
|
||||||
|
final apiModeConfigProvider = Provider<ApiModeConfig>((ref) {
|
||||||
|
// Default to HTTP for safety during transition
|
||||||
|
return ApiModeConfig.development;
|
||||||
|
});
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Core Service Providers
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
final authServiceProvider = Provider<AuthService>((ref) {
|
final authServiceProvider = Provider<AuthService>((ref) {
|
||||||
return AuthService(config: AuthConfig.development);
|
return AuthService(config: AuthConfig.development);
|
||||||
});
|
});
|
||||||
@ -21,6 +117,31 @@ final apiClientProvider = Provider<CqrsApiClient>((ref) {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/// Provider for the gRPC-based CQRS API client.
|
||||||
|
///
|
||||||
|
/// Uses auto-dispose to properly shut down the gRPC channel when the provider
|
||||||
|
/// is no longer being watched. This ensures network resources are cleaned up.
|
||||||
|
///
|
||||||
|
/// Example usage:
|
||||||
|
/// ```dart
|
||||||
|
/// final grpcClient = ref.watch(grpcClientProvider);
|
||||||
|
/// final result = await grpcClient.getDeliveryRoutes();
|
||||||
|
/// ```
|
||||||
|
final grpcClientProvider = Provider.autoDispose<GrpcCqrsApiClient>((ref) {
|
||||||
|
final authService = ref.watch(authServiceProvider);
|
||||||
|
final client = GrpcCqrsApiClient(
|
||||||
|
config: GrpcConfig.development,
|
||||||
|
authService: authService,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Register disposal callback to clean up gRPC channel resources
|
||||||
|
ref.onDispose(() {
|
||||||
|
client.shutdown();
|
||||||
|
});
|
||||||
|
|
||||||
|
return client;
|
||||||
|
});
|
||||||
|
|
||||||
final isAuthenticatedProvider = FutureProvider<bool>((ref) async {
|
final isAuthenticatedProvider = FutureProvider<bool>((ref) async {
|
||||||
final authService = ref.watch(authServiceProvider);
|
final authService = ref.watch(authServiceProvider);
|
||||||
return await authService.isAuthenticated();
|
return await authService.isAuthenticated();
|
||||||
@ -38,7 +159,9 @@ final authTokenProvider = FutureProvider<String?>((ref) async {
|
|||||||
return await authService.getToken();
|
return await authService.getToken();
|
||||||
});
|
});
|
||||||
|
|
||||||
final deliveryRoutesProvider = FutureProvider<List<DeliveryRoute>>((ref) async {
|
/// Internal HTTP-based delivery routes provider.
|
||||||
|
/// Use [deliveryRoutesProvider] instead, which respects the API mode configuration.
|
||||||
|
final _httpDeliveryRoutesProvider = FutureProvider<List<DeliveryRoute>>((ref) async {
|
||||||
final authService = ref.watch(authServiceProvider);
|
final authService = ref.watch(authServiceProvider);
|
||||||
final isAuthenticated = await authService.isAuthenticated();
|
final isAuthenticated = await authService.isAuthenticated();
|
||||||
|
|
||||||
@ -68,7 +191,120 @@ final deliveryRoutesProvider = FutureProvider<List<DeliveryRoute>>((ref) async {
|
|||||||
return result.whenSuccess((routes) => routes) ?? [];
|
return result.whenSuccess((routes) => routes) ?? [];
|
||||||
});
|
});
|
||||||
|
|
||||||
final deliveriesProvider = FutureProvider.family<List<Delivery>, int>((ref, routeFragmentId) async {
|
/// Unified delivery routes provider that respects the API mode configuration.
|
||||||
|
///
|
||||||
|
/// Automatically switches between HTTP and gRPC based on [apiModeConfigProvider].
|
||||||
|
/// When gRPC mode is enabled and [ApiModeConfig.fallbackToHttpOnError] is true,
|
||||||
|
/// falls back to HTTP on gRPC failures.
|
||||||
|
///
|
||||||
|
/// Example usage:
|
||||||
|
/// ```dart
|
||||||
|
/// final routes = ref.watch(deliveryRoutesProvider);
|
||||||
|
/// routes.when(
|
||||||
|
/// data: (data) => displayRoutes(data),
|
||||||
|
/// loading: () => showLoading(),
|
||||||
|
/// error: (error, stack) => showError(error),
|
||||||
|
/// );
|
||||||
|
/// ```
|
||||||
|
final deliveryRoutesProvider = FutureProvider<List<DeliveryRoute>>((ref) async {
|
||||||
|
final apiModeConfig = ref.watch(apiModeConfigProvider);
|
||||||
|
|
||||||
|
if (apiModeConfig.isGrpc) {
|
||||||
|
try {
|
||||||
|
return await ref.watch(grpcDeliveryRoutesProvider.future);
|
||||||
|
} catch (e) {
|
||||||
|
if (apiModeConfig.fallbackToHttpOnError) {
|
||||||
|
debugPrint('gRPC failed, falling back to HTTP: $e');
|
||||||
|
return await ref.watch(_httpDeliveryRoutesProvider.future);
|
||||||
|
}
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return await ref.watch(_httpDeliveryRoutesProvider.future);
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Provider for delivery routes using gRPC.
|
||||||
|
///
|
||||||
|
/// This is the gRPC-based alternative to [deliveryRoutesProvider].
|
||||||
|
/// Uses [GrpcCqrsApiClient] for improved performance and type safety.
|
||||||
|
///
|
||||||
|
/// Example usage:
|
||||||
|
/// ```dart
|
||||||
|
/// final routes = ref.watch(grpcDeliveryRoutesProvider);
|
||||||
|
/// routes.when(
|
||||||
|
/// data: (data) => displayRoutes(data),
|
||||||
|
/// loading: () => showLoading(),
|
||||||
|
/// error: (error, stack) => showError(error),
|
||||||
|
/// );
|
||||||
|
/// ```
|
||||||
|
final grpcDeliveryRoutesProvider = FutureProvider<List<DeliveryRoute>>((ref) async {
|
||||||
|
final authService = ref.watch(authServiceProvider);
|
||||||
|
final isAuthenticated = await authService.isAuthenticated();
|
||||||
|
|
||||||
|
if (!isAuthenticated) {
|
||||||
|
throw Exception('User not authenticated');
|
||||||
|
}
|
||||||
|
|
||||||
|
final grpcClient = ref.watch(grpcClientProvider);
|
||||||
|
final result = await grpcClient.getDeliveryRoutes();
|
||||||
|
|
||||||
|
return result.when(
|
||||||
|
success: (routes) => routes,
|
||||||
|
onError: (error) {
|
||||||
|
debugPrint('ERROR fetching delivery routes via gRPC: ${error.message}');
|
||||||
|
if (error.originalException != null) {
|
||||||
|
debugPrint('Original exception: ${error.originalException}');
|
||||||
|
}
|
||||||
|
throw Exception(error.message);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Provider for deliveries using gRPC.
|
||||||
|
///
|
||||||
|
/// This is the gRPC-based alternative to [deliveriesProvider].
|
||||||
|
/// Uses [GrpcCqrsApiClient] for improved performance and type safety.
|
||||||
|
/// Takes a [routeFragmentId] parameter to fetch deliveries for a specific route.
|
||||||
|
///
|
||||||
|
/// Example usage:
|
||||||
|
/// ```dart
|
||||||
|
/// final deliveries = ref.watch(grpcDeliveriesProvider(routeFragmentId));
|
||||||
|
/// deliveries.when(
|
||||||
|
/// data: (data) => displayDeliveries(data),
|
||||||
|
/// loading: () => showLoading(),
|
||||||
|
/// error: (error, stack) => showError(error),
|
||||||
|
/// );
|
||||||
|
/// ```
|
||||||
|
final grpcDeliveriesProvider = FutureProvider.family<List<Delivery>, int>((ref, routeFragmentId) async {
|
||||||
|
final authService = ref.watch(authServiceProvider);
|
||||||
|
final isAuthenticated = await authService.isAuthenticated();
|
||||||
|
|
||||||
|
if (!isAuthenticated) {
|
||||||
|
throw Exception('User not authenticated');
|
||||||
|
}
|
||||||
|
|
||||||
|
final grpcClient = ref.watch(grpcClientProvider);
|
||||||
|
final result = await grpcClient.getDeliveries(routeFragmentId: routeFragmentId);
|
||||||
|
|
||||||
|
final deliveries = result.when(
|
||||||
|
success: (deliveries) => deliveries,
|
||||||
|
onError: (error) {
|
||||||
|
debugPrint('ERROR fetching deliveries for route $routeFragmentId via gRPC: ${error.message}');
|
||||||
|
if (error.originalException != null) {
|
||||||
|
debugPrint('Original exception: ${error.originalException}');
|
||||||
|
}
|
||||||
|
throw Exception(error.message);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// Always append the warehouse delivery at the end
|
||||||
|
return [...deliveries, Delivery.createWarehouseDelivery()];
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Internal HTTP-based deliveries provider.
|
||||||
|
/// Use [deliveriesProvider] instead, which respects the API mode configuration.
|
||||||
|
final _httpDeliveriesProvider = FutureProvider.family<List<Delivery>, int>((ref, routeFragmentId) async {
|
||||||
final authService = ref.watch(authServiceProvider);
|
final authService = ref.watch(authServiceProvider);
|
||||||
final isAuthenticated = await authService.isAuthenticated();
|
final isAuthenticated = await authService.isAuthenticated();
|
||||||
|
|
||||||
@ -108,6 +344,41 @@ final deliveriesProvider = FutureProvider.family<List<Delivery>, int>((ref, rout
|
|||||||
return [...deliveries, Delivery.createWarehouseDelivery()];
|
return [...deliveries, Delivery.createWarehouseDelivery()];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/// Unified deliveries provider that respects the API mode configuration.
|
||||||
|
///
|
||||||
|
/// Automatically switches between HTTP and gRPC based on [apiModeConfigProvider].
|
||||||
|
/// When gRPC mode is enabled and [ApiModeConfig.fallbackToHttpOnError] is true,
|
||||||
|
/// falls back to HTTP on gRPC failures.
|
||||||
|
///
|
||||||
|
/// Takes a [routeFragmentId] parameter to fetch deliveries for a specific route.
|
||||||
|
///
|
||||||
|
/// Example usage:
|
||||||
|
/// ```dart
|
||||||
|
/// final deliveries = ref.watch(deliveriesProvider(routeFragmentId));
|
||||||
|
/// deliveries.when(
|
||||||
|
/// data: (data) => displayDeliveries(data),
|
||||||
|
/// loading: () => showLoading(),
|
||||||
|
/// error: (error, stack) => showError(error),
|
||||||
|
/// );
|
||||||
|
/// ```
|
||||||
|
final deliveriesProvider = FutureProvider.family<List<Delivery>, int>((ref, routeFragmentId) async {
|
||||||
|
final apiModeConfig = ref.watch(apiModeConfigProvider);
|
||||||
|
|
||||||
|
if (apiModeConfig.isGrpc) {
|
||||||
|
try {
|
||||||
|
return await ref.watch(grpcDeliveriesProvider(routeFragmentId).future);
|
||||||
|
} catch (e) {
|
||||||
|
if (apiModeConfig.fallbackToHttpOnError) {
|
||||||
|
debugPrint('gRPC failed for route $routeFragmentId, falling back to HTTP: $e');
|
||||||
|
return await ref.watch(_httpDeliveriesProvider(routeFragmentId).future);
|
||||||
|
}
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return await ref.watch(_httpDeliveriesProvider(routeFragmentId).future);
|
||||||
|
});
|
||||||
|
|
||||||
/// Provider to get all deliveries from all routes
|
/// Provider to get all deliveries from all routes
|
||||||
final allDeliveriesProvider = FutureProvider<List<Delivery>>((ref) async {
|
final allDeliveriesProvider = FutureProvider<List<Delivery>>((ref) async {
|
||||||
final routes = await ref.read(deliveryRoutesProvider.future);
|
final routes = await ref.read(deliveryRoutesProvider.future);
|
||||||
|
|||||||
51
pubspec.lock
51
pubspec.lock
@ -266,7 +266,7 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "0.9.3+4"
|
version: "0.9.3+4"
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: fixnum
|
name: fixnum
|
||||||
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
|
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
|
||||||
@ -387,6 +387,13 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.3"
|
version: "0.1.3"
|
||||||
|
flutter_svrnty_cqrs_datasource:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
path: "/Users/mathias/Documents/workspaces/svrnty/flutter_cqrs_datasource"
|
||||||
|
relative: false
|
||||||
|
source: path
|
||||||
|
version: "0.0.1"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -437,6 +444,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "17.0.1"
|
version: "17.0.1"
|
||||||
|
google_identity_services_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: google_identity_services_web
|
||||||
|
sha256: "5d187c46dc59e02646e10fe82665fc3884a9b71bc1c90c2b8b749316d33ee454"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.3.3+1"
|
||||||
google_navigation_flutter:
|
google_navigation_flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -445,6 +460,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.8.2"
|
version: "0.8.2"
|
||||||
|
googleapis_auth:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: googleapis_auth
|
||||||
|
sha256: b81fe352cc4a330b3710d2b7ad258d9bcef6f909bb759b306bf42973a7d046db
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.0"
|
||||||
graphs:
|
graphs:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -453,6 +476,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.2"
|
version: "2.3.2"
|
||||||
|
grpc:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: grpc
|
||||||
|
sha256: "86be3a7d39ad865b214a7370021ac80e68939238b507730de6d97fc662cb2723"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.1.0"
|
||||||
http:
|
http:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -461,6 +492,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.6.0"
|
version: "1.6.0"
|
||||||
|
http2:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: http2
|
||||||
|
sha256: "382d3aefc5bd6dc68c6b892d7664f29b5beb3251611ae946a98d35158a82bbfa"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.3.1"
|
||||||
http_interceptor:
|
http_interceptor:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -845,6 +884,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.3"
|
version: "6.0.3"
|
||||||
|
protobuf:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: protobuf
|
||||||
|
sha256: "75ec242d22e950bdcc79ee38dd520ce4ee0bc491d7fadc4ea47694604d22bf06"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.0.0"
|
||||||
pub_semver:
|
pub_semver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1251,5 +1298,5 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.3"
|
version: "3.1.3"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.9.2 <4.0.0"
|
dart: ">=3.10.1 <4.0.0"
|
||||||
flutter: ">=3.35.0"
|
flutter: ">=3.35.0"
|
||||||
|
|||||||
@ -42,6 +42,13 @@ dependencies:
|
|||||||
http_interceptor: ^2.0.0
|
http_interceptor: ^2.0.0
|
||||||
google_navigation_flutter: ^0.8.2
|
google_navigation_flutter: ^0.8.2
|
||||||
|
|
||||||
|
# gRPC dependencies for API migration
|
||||||
|
flutter_svrnty_cqrs_datasource:
|
||||||
|
path: /Users/mathias/Documents/workspaces/svrnty/flutter_cqrs_datasource
|
||||||
|
grpc: ^5.1.0
|
||||||
|
protobuf: ^6.0.0
|
||||||
|
fixnum: ^1.1.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|||||||
67
test/api/api_mode_config_test.dart
Normal file
67
test/api/api_mode_config_test.dart
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:planb_logistic/providers/providers.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('ApiMode', () {
|
||||||
|
test('has correct values', () {
|
||||||
|
expect(ApiMode.values.length, equals(2));
|
||||||
|
expect(ApiMode.values, contains(ApiMode.http));
|
||||||
|
expect(ApiMode.values, contains(ApiMode.grpc));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group('ApiModeConfig', () {
|
||||||
|
test('development config defaults to HTTP', () {
|
||||||
|
const config = ApiModeConfig.development;
|
||||||
|
|
||||||
|
expect(config.mode, equals(ApiMode.http));
|
||||||
|
expect(config.isHttp, isTrue);
|
||||||
|
expect(config.isGrpc, isFalse);
|
||||||
|
expect(config.fallbackToHttpOnError, isTrue);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('developmentGrpc config uses gRPC', () {
|
||||||
|
const config = ApiModeConfig.developmentGrpc;
|
||||||
|
|
||||||
|
expect(config.mode, equals(ApiMode.grpc));
|
||||||
|
expect(config.isGrpc, isTrue);
|
||||||
|
expect(config.isHttp, isFalse);
|
||||||
|
expect(config.fallbackToHttpOnError, isTrue);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('production config defaults to HTTP', () {
|
||||||
|
const config = ApiModeConfig.production;
|
||||||
|
|
||||||
|
expect(config.mode, equals(ApiMode.http));
|
||||||
|
expect(config.isHttp, isTrue);
|
||||||
|
expect(config.isGrpc, isFalse);
|
||||||
|
expect(config.fallbackToHttpOnError, isFalse);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('productionGrpc config uses gRPC without fallback', () {
|
||||||
|
const config = ApiModeConfig.productionGrpc;
|
||||||
|
|
||||||
|
expect(config.mode, equals(ApiMode.grpc));
|
||||||
|
expect(config.isGrpc, isTrue);
|
||||||
|
expect(config.isHttp, isFalse);
|
||||||
|
expect(config.fallbackToHttpOnError, isFalse);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('custom config can be created', () {
|
||||||
|
const config = ApiModeConfig(
|
||||||
|
mode: ApiMode.grpc,
|
||||||
|
fallbackToHttpOnError: false,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(config.mode, equals(ApiMode.grpc));
|
||||||
|
expect(config.isGrpc, isTrue);
|
||||||
|
expect(config.fallbackToHttpOnError, isFalse);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('default fallbackToHttpOnError is true', () {
|
||||||
|
const config = ApiModeConfig(mode: ApiMode.grpc);
|
||||||
|
|
||||||
|
expect(config.fallbackToHttpOnError, isTrue);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
85
test/api/grpc_client_test.dart
Normal file
85
test/api/grpc_client_test.dart
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:planb_logistic/api/grpc_client.dart';
|
||||||
|
import 'package:planb_logistic/api/grpc_config.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('GrpcCqrsApiClient', () {
|
||||||
|
test('can be created with development config', () {
|
||||||
|
final client = GrpcCqrsApiClient(
|
||||||
|
config: GrpcConfig.development,
|
||||||
|
authService: null,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(client.config, equals(GrpcConfig.development));
|
||||||
|
expect(client.isConnected, isFalse);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('can be created with production config', () {
|
||||||
|
final client = GrpcCqrsApiClient(
|
||||||
|
config: GrpcConfig.production,
|
||||||
|
authService: null,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(client.config, equals(GrpcConfig.production));
|
||||||
|
expect(client.isConnected, isFalse);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('channel is created lazily', () {
|
||||||
|
final client = GrpcCqrsApiClient(
|
||||||
|
config: GrpcConfig.development,
|
||||||
|
authService: null,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(client.isConnected, isFalse);
|
||||||
|
|
||||||
|
// Access the channel to trigger lazy initialization
|
||||||
|
final channel = client.channel;
|
||||||
|
|
||||||
|
expect(channel, isNotNull);
|
||||||
|
expect(client.isConnected, isTrue);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('delivery client is created lazily', () {
|
||||||
|
final client = GrpcCqrsApiClient(
|
||||||
|
config: GrpcConfig.development,
|
||||||
|
authService: null,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Access delivery client (implicitly creates channel first)
|
||||||
|
final deliveryClient = client.deliveryClient;
|
||||||
|
|
||||||
|
expect(deliveryClient, isNotNull);
|
||||||
|
expect(client.isConnected, isTrue);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('shutdown clears channel and client', () async {
|
||||||
|
final client = GrpcCqrsApiClient(
|
||||||
|
config: GrpcConfig.development,
|
||||||
|
authService: null,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Initialize the channel
|
||||||
|
final _ = client.channel;
|
||||||
|
expect(client.isConnected, isTrue);
|
||||||
|
|
||||||
|
// Shutdown
|
||||||
|
await client.shutdown();
|
||||||
|
expect(client.isConnected, isFalse);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('terminate clears channel and client', () async {
|
||||||
|
final client = GrpcCqrsApiClient(
|
||||||
|
config: GrpcConfig.development,
|
||||||
|
authService: null,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Initialize the channel
|
||||||
|
final _ = client.channel;
|
||||||
|
expect(client.isConnected, isTrue);
|
||||||
|
|
||||||
|
// Terminate
|
||||||
|
await client.terminate();
|
||||||
|
expect(client.isConnected, isFalse);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
56
test/api/grpc_config_test.dart
Normal file
56
test/api/grpc_config_test.dart
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:planb_logistic/api/grpc_config.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('GrpcConfig', () {
|
||||||
|
test('development config has correct values', () {
|
||||||
|
const config = GrpcConfig.development;
|
||||||
|
|
||||||
|
expect(config.host, equals('192.168.88.228'));
|
||||||
|
expect(config.port, equals(5011));
|
||||||
|
expect(config.useTls, isFalse);
|
||||||
|
expect(config.allowSelfSignedCertificate, isTrue);
|
||||||
|
expect(config.timeout, equals(const Duration(seconds: 30)));
|
||||||
|
expect(config.address, equals('192.168.88.228:5011'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('production config has correct values', () {
|
||||||
|
const config = GrpcConfig.production;
|
||||||
|
|
||||||
|
expect(config.host, equals('grpc-route.goutezplanb.com'));
|
||||||
|
expect(config.port, equals(443));
|
||||||
|
expect(config.useTls, isTrue);
|
||||||
|
expect(config.allowSelfSignedCertificate, isFalse);
|
||||||
|
expect(config.timeout, equals(const Duration(seconds: 30)));
|
||||||
|
expect(config.address, equals('grpc-route.goutezplanb.com:443'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('custom config can be created', () {
|
||||||
|
const config = GrpcConfig(
|
||||||
|
host: 'custom.example.com',
|
||||||
|
port: 9000,
|
||||||
|
timeout: Duration(seconds: 60),
|
||||||
|
useTls: true,
|
||||||
|
allowSelfSignedCertificate: true,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(config.host, equals('custom.example.com'));
|
||||||
|
expect(config.port, equals(9000));
|
||||||
|
expect(config.useTls, isTrue);
|
||||||
|
expect(config.allowSelfSignedCertificate, isTrue);
|
||||||
|
expect(config.timeout, equals(const Duration(seconds: 60)));
|
||||||
|
expect(config.address, equals('custom.example.com:9000'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('default values are correctly applied', () {
|
||||||
|
const config = GrpcConfig(
|
||||||
|
host: 'test.example.com',
|
||||||
|
port: 443,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(config.useTls, isTrue);
|
||||||
|
expect(config.allowSelfSignedCertificate, isFalse);
|
||||||
|
expect(config.timeout, equals(const Duration(seconds: 30)));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
192
test/e2e/GRPC_E2E_VERIFICATION.md
Normal file
192
test/e2e/GRPC_E2E_VERIFICATION.md
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
# gRPC Integration E2E Verification Guide
|
||||||
|
|
||||||
|
This document provides steps for verifying the gRPC integration end-to-end.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
1. gRPC backend server running at `192.168.88.228:5011`
|
||||||
|
2. Flutter environment configured
|
||||||
|
3. Valid test credentials for authentication
|
||||||
|
|
||||||
|
## Step 1: Enable gRPC Mode
|
||||||
|
|
||||||
|
To enable gRPC mode, override the `apiModeConfigProvider` in the app's `ProviderScope`:
|
||||||
|
|
||||||
|
### Option A: Code Change (for testing)
|
||||||
|
|
||||||
|
Edit `lib/main.dart` to add the provider override:
|
||||||
|
|
||||||
|
```dart
|
||||||
|
import 'package:planb_logistic/providers/providers.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
runApp(
|
||||||
|
ProviderScope(
|
||||||
|
overrides: [
|
||||||
|
// Enable gRPC mode with fallback to HTTP
|
||||||
|
apiModeConfigProvider.overrideWithValue(ApiModeConfig.developmentGrpc),
|
||||||
|
],
|
||||||
|
child: const MyApp(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option B: Environment-Based Toggle
|
||||||
|
|
||||||
|
The app can also be configured to check an environment variable or build flag:
|
||||||
|
|
||||||
|
```dart
|
||||||
|
final useGrpc = const bool.fromEnvironment('USE_GRPC', defaultValue: false);
|
||||||
|
final apiMode = useGrpc ? ApiModeConfig.developmentGrpc : ApiModeConfig.development;
|
||||||
|
```
|
||||||
|
|
||||||
|
Then run with:
|
||||||
|
```bash
|
||||||
|
flutter run -d chrome --dart-define=USE_GRPC=true
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 2: Login to App
|
||||||
|
|
||||||
|
1. Launch the app in Chrome browser:
|
||||||
|
```bash
|
||||||
|
flutter run -d chrome
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Click "Login with Keycloak" button
|
||||||
|
3. Enter valid credentials
|
||||||
|
4. Wait for redirect back to the app
|
||||||
|
|
||||||
|
**Expected:** User is authenticated and redirected to the main app.
|
||||||
|
|
||||||
|
## Step 3: Navigate to Routes Page
|
||||||
|
|
||||||
|
1. After login, navigate to the Routes page
|
||||||
|
2. The app should fetch delivery routes via gRPC
|
||||||
|
|
||||||
|
**Expected Behavior:**
|
||||||
|
- Routes list should populate with delivery route data
|
||||||
|
- No console errors related to gRPC
|
||||||
|
- In browser DevTools console, you should see:
|
||||||
|
- No "gRPC failed" messages (unless backend is unavailable)
|
||||||
|
- If gRPC fails and fallback is enabled, you may see: "gRPC failed, falling back to HTTP: ..."
|
||||||
|
|
||||||
|
**Verification Points:**
|
||||||
|
- Routes display with correct data (id, name, deliveries count)
|
||||||
|
- Loading indicator shows during fetch
|
||||||
|
- Error state handled gracefully if backend unavailable
|
||||||
|
|
||||||
|
## Step 4: Select a Route - Verify Deliveries Load
|
||||||
|
|
||||||
|
1. Click on a route from the list
|
||||||
|
2. Navigate to the deliveries page for that route
|
||||||
|
|
||||||
|
**Expected Behavior:**
|
||||||
|
- Deliveries list should populate with delivery data for the selected route
|
||||||
|
- Each delivery should show:
|
||||||
|
- Delivery index/number
|
||||||
|
- Customer name
|
||||||
|
- Address information
|
||||||
|
- Status (delivered/pending/skipped)
|
||||||
|
- Warehouse delivery should appear at the end of the list
|
||||||
|
|
||||||
|
**Verification Points:**
|
||||||
|
- Correct number of deliveries loaded
|
||||||
|
- All delivery fields properly mapped from gRPC response
|
||||||
|
- Warehouse delivery appended correctly
|
||||||
|
|
||||||
|
## Step 5: Mark a Delivery Complete
|
||||||
|
|
||||||
|
1. Select an uncompleted delivery
|
||||||
|
2. Mark it as complete (tap completion button)
|
||||||
|
|
||||||
|
**Expected Behavior:**
|
||||||
|
- Command sent via gRPC to `completeDelivery` endpoint
|
||||||
|
- Delivery status updates to "completed"
|
||||||
|
- UI refreshes to show new status
|
||||||
|
|
||||||
|
**Verification Points:**
|
||||||
|
- No error messages
|
||||||
|
- Delivery marked as completed in the list
|
||||||
|
- Timestamp recorded for completion
|
||||||
|
|
||||||
|
## Step 6: Check Browser Console for gRPC Logs
|
||||||
|
|
||||||
|
Open browser DevTools (F12) and check the Console tab for:
|
||||||
|
|
||||||
|
### Success Indicators:
|
||||||
|
- No error messages related to gRPC
|
||||||
|
- Successful data loading without fallback messages
|
||||||
|
|
||||||
|
### Warning Indicators (acceptable):
|
||||||
|
- "gRPC failed, falling back to HTTP: ..." - indicates gRPC failed but HTTP fallback worked
|
||||||
|
|
||||||
|
### Error Indicators (need investigation):
|
||||||
|
- "UNAUTHENTICATED" errors - token issue
|
||||||
|
- "UNAVAILABLE" errors - backend not reachable
|
||||||
|
- "DEADLINE_EXCEEDED" errors - timeout
|
||||||
|
- Unhandled exceptions
|
||||||
|
|
||||||
|
## Verification Checklist
|
||||||
|
|
||||||
|
| Step | Check | Status |
|
||||||
|
|------|-------|--------|
|
||||||
|
| 1 | gRPC mode enabled via provider override | [ ] |
|
||||||
|
| 2 | Login successful | [ ] |
|
||||||
|
| 3 | Routes load (via gRPC or HTTP fallback) | [ ] |
|
||||||
|
| 4 | Deliveries load for selected route | [ ] |
|
||||||
|
| 5 | Complete delivery command works | [ ] |
|
||||||
|
| 6 | No critical console errors | [ ] |
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### gRPC Backend Unavailable
|
||||||
|
|
||||||
|
If the gRPC backend at `192.168.88.228:5011` is not reachable:
|
||||||
|
|
||||||
|
1. **With fallback enabled (default):** App falls back to HTTP automatically
|
||||||
|
2. **Without fallback:** App shows error state
|
||||||
|
|
||||||
|
To test with HTTP only:
|
||||||
|
```dart
|
||||||
|
apiModeConfigProvider.overrideWithValue(ApiModeConfig.development)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Authentication Issues
|
||||||
|
|
||||||
|
If you see UNAUTHENTICATED errors:
|
||||||
|
|
||||||
|
1. Check that the auth token is valid
|
||||||
|
2. Try logging out and back in
|
||||||
|
3. Verify the token is being sent in gRPC metadata
|
||||||
|
|
||||||
|
### Connection Timeout
|
||||||
|
|
||||||
|
If requests are timing out:
|
||||||
|
|
||||||
|
1. Check network connectivity to `192.168.88.228:5011`
|
||||||
|
2. Verify the backend server is running
|
||||||
|
3. Check firewall/VPN settings
|
||||||
|
|
||||||
|
## Production Configuration
|
||||||
|
|
||||||
|
For production deployment, use:
|
||||||
|
|
||||||
|
```dart
|
||||||
|
apiModeConfigProvider.overrideWithValue(ApiModeConfig.productionGrpc)
|
||||||
|
```
|
||||||
|
|
||||||
|
This connects to `grpc-route.goutezplanb.com:443` with TLS enabled.
|
||||||
|
|
||||||
|
## Test Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run unit tests (no backend required)
|
||||||
|
flutter test
|
||||||
|
|
||||||
|
# Run with gRPC enabled
|
||||||
|
flutter run -d chrome --dart-define=USE_GRPC=true
|
||||||
|
|
||||||
|
# Check gRPC backend is reachable (requires grpcurl)
|
||||||
|
grpcurl -plaintext 192.168.88.228:5011 list
|
||||||
|
```
|
||||||
Loading…
Reference in New Issue
Block a user