read from and generate grpc service metadata (#991)
diff --git a/protoc_plugin/CHANGELOG.md b/protoc_plugin/CHANGELOG.md index 5c5fe95..012572d 100644 --- a/protoc_plugin/CHANGELOG.md +++ b/protoc_plugin/CHANGELOG.md
@@ -1,7 +1,38 @@ -## 22.1.1-wip +## 22.2.0 +* Read `default_host` and `oauth_scopes` options from gRPC service definitions + and write that information to the generated gRPC clients. * Generate dartdocs for grpc services ([#973]). +We now parse and generate code cooresponding to the proto options +`google.api.default_host` and `google.api.oauth_scopes`: + +```proto +service Firestore { + option (google.api.default_host) = "firestore.googleapis.com"; + option (google.api.oauth_scopes) = + "https://www.googleapis.com/auth/cloud-platform," + "https://www.googleapis.com/auth/datastore"; + + ... +``` + +Will generate as: + +```dart +class FirestoreClient extends $grpc.Client { + /// The hostname for this service. + static const $core.String defaultHost = 'firestore.googleapis.com'; + + /// OAuth scopes needed for the client. + static const $core.List<$core.String> oauthScopes = [ + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/datastore', + ]; + + ... +``` + [#973]: https://github.com/google/protobuf.dart/issues/973 ## 22.1.0
diff --git a/protoc_plugin/Makefile b/protoc_plugin/Makefile index 6c04fa5..9b68b43 100644 --- a/protoc_plugin/Makefile +++ b/protoc_plugin/Makefile
@@ -77,7 +77,7 @@ TEST_PROTO_SRCS=$(foreach proto, $(TEST_PROTO_LIST), \ $(TEST_PROTO_SRC_DIR)/$(proto).proto) -PREGENERATED_SRCS=protos/descriptor.proto protos/plugin.proto protos/dart_options.proto +PREGENERATED_SRCS=protos/descriptor.proto protos/client.proto protos/plugin.proto protos/dart_options.proto $(TEST_PROTO_LIBS): $(PLUGIN_SRC) $(TEST_PROTO_SRCS) mkdir -p $(TEST_PROTO_DIR) @@ -104,6 +104,7 @@ update-pregenerated: $(PLUGIN_PATH) $(PREGENERATED_SRCS) protoc --dart_out=lib/src/generated -Iprotos --plugin=protoc-gen-dart=$(realpath $(PLUGIN_PATH)) $(PREGENERATED_SRCS) + rm lib/src/generated/client.pb{json,server}.dart rm lib/src/generated/descriptor.pb{json,server}.dart rm lib/src/generated/dart_options.pb{enum,json,server}.dart rm lib/src/generated/plugin.pb{json,server}.dart
diff --git a/protoc_plugin/lib/protoc.dart b/protoc_plugin/lib/protoc.dart index e6d175b..8020405 100644 --- a/protoc_plugin/lib/protoc.dart +++ b/protoc_plugin/lib/protoc.dart
@@ -7,6 +7,7 @@ import 'mixins.dart'; import 'names.dart'; import 'src/code_generator.dart'; +import 'src/generated/client.pb.dart'; import 'src/generated/dart_options.pb.dart'; import 'src/generated/descriptor.pb.dart'; import 'src/generated/plugin.pb.dart';
diff --git a/protoc_plugin/lib/src/code_generator.dart b/protoc_plugin/lib/src/code_generator.dart index dd4c19f..45cfe55 100644 --- a/protoc_plugin/lib/src/code_generator.dart +++ b/protoc_plugin/lib/src/code_generator.dart
@@ -11,6 +11,7 @@ import '../names.dart' show lowerCaseFirstLetter; import '../protoc.dart' show FileGenerator; +import 'generated/client.pb.dart'; import 'generated/dart_options.pb.dart'; import 'generated/plugin.pb.dart'; import 'linker.dart'; @@ -87,57 +88,57 @@ /// for details), and [config] can be used to override where /// generated files are created and how imports between generated files are /// constructed (see [OutputConfiguration] for details). - void generate( - {Map<String, SingleOptionParser>? optionParsers, - OutputConfiguration config = const DefaultOutputConfiguration()}) { + Future<void> generate({ + Map<String, SingleOptionParser>? optionParsers, + OutputConfiguration config = const DefaultOutputConfiguration(), + }) async { final extensions = ExtensionRegistry(); + Dart_options.registerAllExtensions(extensions); + Client.registerAllExtensions(extensions); - _streamIn - .fold( - BytesBuilder(), (BytesBuilder builder, data) => builder..add(data)) - .then((builder) => builder.takeBytes()) - .then((List<int> bytes) { - // Suppress CodedBufferReader builtin size limitation when reading - // the request, as protobuf definitions can be larger than default - // limit of 64Mb. - final reader = CodedBufferReader(bytes, sizeLimit: bytes.length); - final request = CodeGeneratorRequest(); - request.mergeFromCodedBufferReader(reader, extensions); - reader.checkLastTagWas(0); + final builder = await _streamIn.fold( + BytesBuilder(), + (builder, data) => builder..add(data), + ); + final bytes = builder.takeBytes(); + // Suppress CodedBufferReader builtin size limitation when reading the + // request; protobuf definitions can be larger than default limit of 64Mb. + final reader = CodedBufferReader(bytes, sizeLimit: bytes.length); + final request = CodeGeneratorRequest(); + request.mergeFromCodedBufferReader(reader, extensions); + reader.checkLastTagWas(0); - request.protoFile.sortBy((desc) => desc.name); + request.protoFile.sortBy((desc) => desc.name); - final response = CodeGeneratorResponse(); + final response = CodeGeneratorResponse(); - // Parse the options in the request. Return the errors if any. - final options = parseGenerationOptions(request, response, optionParsers); - if (options == null) { - _streamOut.add(response.writeToBuffer()); - return; - } - - // Create a syntax tree for each .proto file given to us. - // (We may import it even if we don't generate the .pb.dart file.) - final generators = <FileGenerator>[]; - for (final file in request.protoFile) { - generators.add(FileGenerator(file, options)); - } - - // Collect field types and importable files. - link(options, generators); - - // Generate the .pb.dart file if requested. - for (final gen in generators) { - final name = gen.descriptor.name; - if (request.fileToGenerate.contains(name)) { - response.file.addAll(gen.generateFiles(config)); - } - } - response.supportedFeatures = - Int64(CodeGeneratorResponse_Feature.FEATURE_PROTO3_OPTIONAL.value); - + // Parse the options in the request. Return the errors if any. + final options = parseGenerationOptions(request, response, optionParsers); + if (options == null) { _streamOut.add(response.writeToBuffer()); - }); + return; + } + + // Create a syntax tree for each .proto file given to us. + // (We may import it even if we don't generate the .pb.dart file.) + final generators = <FileGenerator>[]; + for (final file in request.protoFile) { + generators.add(FileGenerator(file, options)); + } + + // Collect field types and importable files. + link(options, generators); + + // Generate the .pb.dart file if requested. + for (final gen in generators) { + final name = gen.descriptor.name; + if (request.fileToGenerate.contains(name)) { + response.file.addAll(gen.generateFiles(config)); + } + } + response.supportedFeatures = + Int64(CodeGeneratorResponse_Feature.FEATURE_PROTO3_OPTIONAL.value); + _streamOut.add(response.writeToBuffer()); } }
diff --git a/protoc_plugin/lib/src/generated/client.pb.dart b/protoc_plugin/lib/src/generated/client.pb.dart new file mode 100644 index 0000000..ccb157d --- /dev/null +++ b/protoc_plugin/lib/src/generated/client.pb.dart
@@ -0,0 +1,1263 @@ +// +// Generated code. Do not modify. +// source: client.proto +// +// @dart = 3.3 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +import 'client.pbenum.dart'; + +export 'package:protobuf/protobuf.dart' show GeneratedMessageGenericExtensions; + +export 'client.pbenum.dart'; + +/// Required information for every language. +class CommonLanguageSettings extends $pb.GeneratedMessage { + factory CommonLanguageSettings({ + @$core.Deprecated('This field is deprecated.') + $core.String? referenceDocsUri, + $core.Iterable<ClientLibraryDestination>? destinations, + SelectiveGapicGeneration? selectiveGapicGeneration, + }) { + final $result = create(); + if (referenceDocsUri != null) { + // ignore: deprecated_member_use_from_same_package + $result.referenceDocsUri = referenceDocsUri; + } + if (destinations != null) { + $result.destinations.addAll(destinations); + } + if (selectiveGapicGeneration != null) { + $result.selectiveGapicGeneration = selectiveGapicGeneration; + } + return $result; + } + CommonLanguageSettings._() : super(); + factory CommonLanguageSettings.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + factory CommonLanguageSettings.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'CommonLanguageSettings', + package: const $pb.PackageName(_omitMessageNames ? '' : 'google.api'), + createEmptyInstance: create) + ..aOS(1, _omitFieldNames ? '' : 'referenceDocsUri') + ..pc<ClientLibraryDestination>( + 2, _omitFieldNames ? '' : 'destinations', $pb.PbFieldType.KE, + valueOf: ClientLibraryDestination.valueOf, + enumValues: ClientLibraryDestination.values, + defaultEnumValue: + ClientLibraryDestination.CLIENT_LIBRARY_DESTINATION_UNSPECIFIED) + ..aOM<SelectiveGapicGeneration>( + 3, _omitFieldNames ? '' : 'selectiveGapicGeneration', + subBuilder: SelectiveGapicGeneration.create) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + CommonLanguageSettings clone() => + CommonLanguageSettings()..mergeFromMessage(this); + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CommonLanguageSettings copyWith( + void Function(CommonLanguageSettings) updates) => + super.copyWith((message) => updates(message as CommonLanguageSettings)) + as CommonLanguageSettings; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static CommonLanguageSettings create() => CommonLanguageSettings._(); + CommonLanguageSettings createEmptyInstance() => create(); + static $pb.PbList<CommonLanguageSettings> createRepeated() => + $pb.PbList<CommonLanguageSettings>(); + @$core.pragma('dart2js:noInline') + static CommonLanguageSettings getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor<CommonLanguageSettings>(create); + static CommonLanguageSettings? _defaultInstance; + + /// Link to automatically generated reference documentation. Example: + /// https://cloud.google.com/nodejs/docs/reference/asset/latest + @$core.Deprecated('This field is deprecated.') + @$pb.TagNumber(1) + $core.String get referenceDocsUri => $_getSZ(0); + @$core.Deprecated('This field is deprecated.') + @$pb.TagNumber(1) + set referenceDocsUri($core.String v) { + $_setString(0, v); + } + + @$core.Deprecated('This field is deprecated.') + @$pb.TagNumber(1) + $core.bool hasReferenceDocsUri() => $_has(0); + @$core.Deprecated('This field is deprecated.') + @$pb.TagNumber(1) + void clearReferenceDocsUri() => $_clearField(1); + + /// The destination where API teams want this client library to be published. + @$pb.TagNumber(2) + $pb.PbList<ClientLibraryDestination> get destinations => $_getList(1); + + /// Configuration for which RPCs should be generated in the GAPIC client. + @$pb.TagNumber(3) + SelectiveGapicGeneration get selectiveGapicGeneration => $_getN(2); + @$pb.TagNumber(3) + set selectiveGapicGeneration(SelectiveGapicGeneration v) { + $_setField(3, v); + } + + @$pb.TagNumber(3) + $core.bool hasSelectiveGapicGeneration() => $_has(2); + @$pb.TagNumber(3) + void clearSelectiveGapicGeneration() => $_clearField(3); + @$pb.TagNumber(3) + SelectiveGapicGeneration ensureSelectiveGapicGeneration() => $_ensure(2); +} + +/// This message configures the settings for publishing [Google Cloud Client +/// libraries](https://cloud.google.com/apis/docs/cloud-client-libraries) +/// generated from the service config. +class Publishing extends $pb.GeneratedMessage { + factory Publishing({ + $core.String? newIssueUri, + $core.String? documentationUri, + $core.String? apiShortName, + $core.String? githubLabel, + $core.Iterable<$core.String>? codeownerGithubTeams, + $core.String? docTagPrefix, + ClientLibraryOrganization? organization, + $core.String? protoReferenceDocumentationUri, + $core.String? restReferenceDocumentationUri, + }) { + final $result = create(); + if (newIssueUri != null) { + $result.newIssueUri = newIssueUri; + } + if (documentationUri != null) { + $result.documentationUri = documentationUri; + } + if (apiShortName != null) { + $result.apiShortName = apiShortName; + } + if (githubLabel != null) { + $result.githubLabel = githubLabel; + } + if (codeownerGithubTeams != null) { + $result.codeownerGithubTeams.addAll(codeownerGithubTeams); + } + if (docTagPrefix != null) { + $result.docTagPrefix = docTagPrefix; + } + if (organization != null) { + $result.organization = organization; + } + if (protoReferenceDocumentationUri != null) { + $result.protoReferenceDocumentationUri = protoReferenceDocumentationUri; + } + if (restReferenceDocumentationUri != null) { + $result.restReferenceDocumentationUri = restReferenceDocumentationUri; + } + return $result; + } + Publishing._() : super(); + factory Publishing.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + factory Publishing.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'Publishing', + package: const $pb.PackageName(_omitMessageNames ? '' : 'google.api'), + createEmptyInstance: create) + ..aOS(101, _omitFieldNames ? '' : 'newIssueUri') + ..aOS(102, _omitFieldNames ? '' : 'documentationUri') + ..aOS(103, _omitFieldNames ? '' : 'apiShortName') + ..aOS(104, _omitFieldNames ? '' : 'githubLabel') + ..pPS(105, _omitFieldNames ? '' : 'codeownerGithubTeams') + ..aOS(106, _omitFieldNames ? '' : 'docTagPrefix') + ..e<ClientLibraryOrganization>( + 107, _omitFieldNames ? '' : 'organization', $pb.PbFieldType.OE, + defaultOrMaker: + ClientLibraryOrganization.CLIENT_LIBRARY_ORGANIZATION_UNSPECIFIED, + valueOf: ClientLibraryOrganization.valueOf, + enumValues: ClientLibraryOrganization.values) + ..aOS(110, _omitFieldNames ? '' : 'protoReferenceDocumentationUri') + ..aOS(111, _omitFieldNames ? '' : 'restReferenceDocumentationUri') + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Publishing clone() => Publishing()..mergeFromMessage(this); + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Publishing copyWith(void Function(Publishing) updates) => + super.copyWith((message) => updates(message as Publishing)) as Publishing; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static Publishing create() => Publishing._(); + Publishing createEmptyInstance() => create(); + static $pb.PbList<Publishing> createRepeated() => $pb.PbList<Publishing>(); + @$core.pragma('dart2js:noInline') + static Publishing getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor<Publishing>(create); + static Publishing? _defaultInstance; + + /// Link to a *public* URI where users can report issues. Example: + /// https://issuetracker.google.com/issues/new?component=190865&template=1161103 + @$pb.TagNumber(101) + $core.String get newIssueUri => $_getSZ(0); + @$pb.TagNumber(101) + set newIssueUri($core.String v) { + $_setString(0, v); + } + + @$pb.TagNumber(101) + $core.bool hasNewIssueUri() => $_has(0); + @$pb.TagNumber(101) + void clearNewIssueUri() => $_clearField(101); + + /// Link to product home page. Example: + /// https://cloud.google.com/asset-inventory/docs/overview + @$pb.TagNumber(102) + $core.String get documentationUri => $_getSZ(1); + @$pb.TagNumber(102) + set documentationUri($core.String v) { + $_setString(1, v); + } + + @$pb.TagNumber(102) + $core.bool hasDocumentationUri() => $_has(1); + @$pb.TagNumber(102) + void clearDocumentationUri() => $_clearField(102); + + /// Used as a tracking tag when collecting data about the APIs developer + /// relations artifacts like docs, packages delivered to package managers, + /// etc. Example: "speech". + @$pb.TagNumber(103) + $core.String get apiShortName => $_getSZ(2); + @$pb.TagNumber(103) + set apiShortName($core.String v) { + $_setString(2, v); + } + + @$pb.TagNumber(103) + $core.bool hasApiShortName() => $_has(2); + @$pb.TagNumber(103) + void clearApiShortName() => $_clearField(103); + + /// GitHub label to apply to issues and pull requests opened for this API. + @$pb.TagNumber(104) + $core.String get githubLabel => $_getSZ(3); + @$pb.TagNumber(104) + set githubLabel($core.String v) { + $_setString(3, v); + } + + @$pb.TagNumber(104) + $core.bool hasGithubLabel() => $_has(3); + @$pb.TagNumber(104) + void clearGithubLabel() => $_clearField(104); + + /// GitHub teams to be added to CODEOWNERS in the directory in GitHub + /// containing source code for the client libraries for this API. + @$pb.TagNumber(105) + $pb.PbList<$core.String> get codeownerGithubTeams => $_getList(4); + + /// A prefix used in sample code when demarking regions to be included in + /// documentation. + @$pb.TagNumber(106) + $core.String get docTagPrefix => $_getSZ(5); + @$pb.TagNumber(106) + set docTagPrefix($core.String v) { + $_setString(5, v); + } + + @$pb.TagNumber(106) + $core.bool hasDocTagPrefix() => $_has(5); + @$pb.TagNumber(106) + void clearDocTagPrefix() => $_clearField(106); + + /// For whom the client library is being published. + @$pb.TagNumber(107) + ClientLibraryOrganization get organization => $_getN(6); + @$pb.TagNumber(107) + set organization(ClientLibraryOrganization v) { + $_setField(107, v); + } + + @$pb.TagNumber(107) + $core.bool hasOrganization() => $_has(6); + @$pb.TagNumber(107) + void clearOrganization() => $_clearField(107); + + /// Optional link to proto reference documentation. Example: + /// https://cloud.google.com/pubsub/lite/docs/reference/rpc + @$pb.TagNumber(110) + $core.String get protoReferenceDocumentationUri => $_getSZ(7); + @$pb.TagNumber(110) + set protoReferenceDocumentationUri($core.String v) { + $_setString(7, v); + } + + @$pb.TagNumber(110) + $core.bool hasProtoReferenceDocumentationUri() => $_has(7); + @$pb.TagNumber(110) + void clearProtoReferenceDocumentationUri() => $_clearField(110); + + /// Optional link to REST reference documentation. Example: + /// https://cloud.google.com/pubsub/lite/docs/reference/rest + @$pb.TagNumber(111) + $core.String get restReferenceDocumentationUri => $_getSZ(8); + @$pb.TagNumber(111) + set restReferenceDocumentationUri($core.String v) { + $_setString(8, v); + } + + @$pb.TagNumber(111) + $core.bool hasRestReferenceDocumentationUri() => $_has(8); + @$pb.TagNumber(111) + void clearRestReferenceDocumentationUri() => $_clearField(111); +} + +/// Settings for Java client libraries. +class JavaSettings extends $pb.GeneratedMessage { + factory JavaSettings({ + $core.String? libraryPackage, + $core.Iterable<$core.MapEntry<$core.String, $core.String>>? + serviceClassNames, + CommonLanguageSettings? common, + }) { + final $result = create(); + if (libraryPackage != null) { + $result.libraryPackage = libraryPackage; + } + if (serviceClassNames != null) { + $result.serviceClassNames.addEntries(serviceClassNames); + } + if (common != null) { + $result.common = common; + } + return $result; + } + JavaSettings._() : super(); + factory JavaSettings.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + factory JavaSettings.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'JavaSettings', + package: const $pb.PackageName(_omitMessageNames ? '' : 'google.api'), + createEmptyInstance: create) + ..aOS(1, _omitFieldNames ? '' : 'libraryPackage') + ..m<$core.String, $core.String>( + 2, _omitFieldNames ? '' : 'serviceClassNames', + entryClassName: 'JavaSettings.ServiceClassNamesEntry', + keyFieldType: $pb.PbFieldType.OS, + valueFieldType: $pb.PbFieldType.OS, + packageName: const $pb.PackageName('google.api')) + ..aOM<CommonLanguageSettings>(3, _omitFieldNames ? '' : 'common', + subBuilder: CommonLanguageSettings.create) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + JavaSettings clone() => JavaSettings()..mergeFromMessage(this); + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + JavaSettings copyWith(void Function(JavaSettings) updates) => + super.copyWith((message) => updates(message as JavaSettings)) + as JavaSettings; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static JavaSettings create() => JavaSettings._(); + JavaSettings createEmptyInstance() => create(); + static $pb.PbList<JavaSettings> createRepeated() => + $pb.PbList<JavaSettings>(); + @$core.pragma('dart2js:noInline') + static JavaSettings getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor<JavaSettings>(create); + static JavaSettings? _defaultInstance; + + /// The package name to use in Java. Clobbers the java_package option + /// set in the protobuf. This should be used **only** by APIs + /// who have already set the language_settings.java.package_name" field + /// in gapic.yaml. API teams should use the protobuf java_package option + /// where possible. + /// + /// Example of a YAML configuration:: + /// + /// publishing: + /// java_settings: + /// library_package: com.google.cloud.pubsub.v1 + @$pb.TagNumber(1) + $core.String get libraryPackage => $_getSZ(0); + @$pb.TagNumber(1) + set libraryPackage($core.String v) { + $_setString(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasLibraryPackage() => $_has(0); + @$pb.TagNumber(1) + void clearLibraryPackage() => $_clearField(1); + + /// Configure the Java class name to use instead of the service's for its + /// corresponding generated GAPIC client. Keys are fully-qualified + /// service names as they appear in the protobuf (including the full + /// the language_settings.java.interface_names" field in gapic.yaml. API + /// teams should otherwise use the service name as it appears in the + /// protobuf. + /// + /// Example of a YAML configuration:: + /// + /// publishing: + /// java_settings: + /// service_class_names: + /// - google.pubsub.v1.Publisher: TopicAdmin + /// - google.pubsub.v1.Subscriber: SubscriptionAdmin + @$pb.TagNumber(2) + $pb.PbMap<$core.String, $core.String> get serviceClassNames => $_getMap(1); + + /// Some settings. + @$pb.TagNumber(3) + CommonLanguageSettings get common => $_getN(2); + @$pb.TagNumber(3) + set common(CommonLanguageSettings v) { + $_setField(3, v); + } + + @$pb.TagNumber(3) + $core.bool hasCommon() => $_has(2); + @$pb.TagNumber(3) + void clearCommon() => $_clearField(3); + @$pb.TagNumber(3) + CommonLanguageSettings ensureCommon() => $_ensure(2); +} + +/// Settings for C++ client libraries. +class CppSettings extends $pb.GeneratedMessage { + factory CppSettings({ + CommonLanguageSettings? common, + }) { + final $result = create(); + if (common != null) { + $result.common = common; + } + return $result; + } + CppSettings._() : super(); + factory CppSettings.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + factory CppSettings.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'CppSettings', + package: const $pb.PackageName(_omitMessageNames ? '' : 'google.api'), + createEmptyInstance: create) + ..aOM<CommonLanguageSettings>(1, _omitFieldNames ? '' : 'common', + subBuilder: CommonLanguageSettings.create) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + CppSettings clone() => CppSettings()..mergeFromMessage(this); + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CppSettings copyWith(void Function(CppSettings) updates) => + super.copyWith((message) => updates(message as CppSettings)) + as CppSettings; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static CppSettings create() => CppSettings._(); + CppSettings createEmptyInstance() => create(); + static $pb.PbList<CppSettings> createRepeated() => $pb.PbList<CppSettings>(); + @$core.pragma('dart2js:noInline') + static CppSettings getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor<CppSettings>(create); + static CppSettings? _defaultInstance; + + /// Some settings. + @$pb.TagNumber(1) + CommonLanguageSettings get common => $_getN(0); + @$pb.TagNumber(1) + set common(CommonLanguageSettings v) { + $_setField(1, v); + } + + @$pb.TagNumber(1) + $core.bool hasCommon() => $_has(0); + @$pb.TagNumber(1) + void clearCommon() => $_clearField(1); + @$pb.TagNumber(1) + CommonLanguageSettings ensureCommon() => $_ensure(0); +} + +/// Settings for Php client libraries. +class PhpSettings extends $pb.GeneratedMessage { + factory PhpSettings({ + CommonLanguageSettings? common, + }) { + final $result = create(); + if (common != null) { + $result.common = common; + } + return $result; + } + PhpSettings._() : super(); + factory PhpSettings.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + factory PhpSettings.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'PhpSettings', + package: const $pb.PackageName(_omitMessageNames ? '' : 'google.api'), + createEmptyInstance: create) + ..aOM<CommonLanguageSettings>(1, _omitFieldNames ? '' : 'common', + subBuilder: CommonLanguageSettings.create) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + PhpSettings clone() => PhpSettings()..mergeFromMessage(this); + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + PhpSettings copyWith(void Function(PhpSettings) updates) => + super.copyWith((message) => updates(message as PhpSettings)) + as PhpSettings; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static PhpSettings create() => PhpSettings._(); + PhpSettings createEmptyInstance() => create(); + static $pb.PbList<PhpSettings> createRepeated() => $pb.PbList<PhpSettings>(); + @$core.pragma('dart2js:noInline') + static PhpSettings getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor<PhpSettings>(create); + static PhpSettings? _defaultInstance; + + /// Some settings. + @$pb.TagNumber(1) + CommonLanguageSettings get common => $_getN(0); + @$pb.TagNumber(1) + set common(CommonLanguageSettings v) { + $_setField(1, v); + } + + @$pb.TagNumber(1) + $core.bool hasCommon() => $_has(0); + @$pb.TagNumber(1) + void clearCommon() => $_clearField(1); + @$pb.TagNumber(1) + CommonLanguageSettings ensureCommon() => $_ensure(0); +} + +/// Experimental features to be included during client library generation. +/// These fields will be deprecated once the feature graduates and is enabled +/// by default. +class PythonSettings_ExperimentalFeatures extends $pb.GeneratedMessage { + factory PythonSettings_ExperimentalFeatures({ + $core.bool? restAsyncIoEnabled, + $core.bool? protobufPythonicTypesEnabled, + $core.bool? unversionedPackageDisabled, + }) { + final $result = create(); + if (restAsyncIoEnabled != null) { + $result.restAsyncIoEnabled = restAsyncIoEnabled; + } + if (protobufPythonicTypesEnabled != null) { + $result.protobufPythonicTypesEnabled = protobufPythonicTypesEnabled; + } + if (unversionedPackageDisabled != null) { + $result.unversionedPackageDisabled = unversionedPackageDisabled; + } + return $result; + } + PythonSettings_ExperimentalFeatures._() : super(); + factory PythonSettings_ExperimentalFeatures.fromBuffer( + $core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + factory PythonSettings_ExperimentalFeatures.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'PythonSettings.ExperimentalFeatures', + package: const $pb.PackageName(_omitMessageNames ? '' : 'google.api'), + createEmptyInstance: create) + ..aOB(1, _omitFieldNames ? '' : 'restAsyncIoEnabled') + ..aOB(2, _omitFieldNames ? '' : 'protobufPythonicTypesEnabled') + ..aOB(3, _omitFieldNames ? '' : 'unversionedPackageDisabled') + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + PythonSettings_ExperimentalFeatures clone() => + PythonSettings_ExperimentalFeatures()..mergeFromMessage(this); + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + PythonSettings_ExperimentalFeatures copyWith( + void Function(PythonSettings_ExperimentalFeatures) updates) => + super.copyWith((message) => + updates(message as PythonSettings_ExperimentalFeatures)) + as PythonSettings_ExperimentalFeatures; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static PythonSettings_ExperimentalFeatures create() => + PythonSettings_ExperimentalFeatures._(); + PythonSettings_ExperimentalFeatures createEmptyInstance() => create(); + static $pb.PbList<PythonSettings_ExperimentalFeatures> createRepeated() => + $pb.PbList<PythonSettings_ExperimentalFeatures>(); + @$core.pragma('dart2js:noInline') + static PythonSettings_ExperimentalFeatures getDefault() => + _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor< + PythonSettings_ExperimentalFeatures>(create); + static PythonSettings_ExperimentalFeatures? _defaultInstance; + + /// Enables generation of asynchronous REST clients if `rest` transport is + /// enabled. By default, asynchronous REST clients will not be generated. + /// This feature will be enabled by default 1 month after launching the + /// feature in preview packages. + @$pb.TagNumber(1) + $core.bool get restAsyncIoEnabled => $_getBF(0); + @$pb.TagNumber(1) + set restAsyncIoEnabled($core.bool v) { + $_setBool(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasRestAsyncIoEnabled() => $_has(0); + @$pb.TagNumber(1) + void clearRestAsyncIoEnabled() => $_clearField(1); + + /// Enables generation of protobuf code using new types that are more + /// Pythonic which are included in `protobuf>=5.29.x`. This feature will be + /// enabled by default 1 month after launching the feature in preview + /// packages. + @$pb.TagNumber(2) + $core.bool get protobufPythonicTypesEnabled => $_getBF(1); + @$pb.TagNumber(2) + set protobufPythonicTypesEnabled($core.bool v) { + $_setBool(1, v); + } + + @$pb.TagNumber(2) + $core.bool hasProtobufPythonicTypesEnabled() => $_has(1); + @$pb.TagNumber(2) + void clearProtobufPythonicTypesEnabled() => $_clearField(2); + + /// Disables generation of an unversioned Python package for this client + /// library. This means that the module names will need to be versioned in + /// import statements. For example `import google.cloud.library_v2` instead + /// of `import google.cloud.library`. + @$pb.TagNumber(3) + $core.bool get unversionedPackageDisabled => $_getBF(2); + @$pb.TagNumber(3) + set unversionedPackageDisabled($core.bool v) { + $_setBool(2, v); + } + + @$pb.TagNumber(3) + $core.bool hasUnversionedPackageDisabled() => $_has(2); + @$pb.TagNumber(3) + void clearUnversionedPackageDisabled() => $_clearField(3); +} + +/// Settings for Python client libraries. +class PythonSettings extends $pb.GeneratedMessage { + factory PythonSettings({ + CommonLanguageSettings? common, + PythonSettings_ExperimentalFeatures? experimentalFeatures, + }) { + final $result = create(); + if (common != null) { + $result.common = common; + } + if (experimentalFeatures != null) { + $result.experimentalFeatures = experimentalFeatures; + } + return $result; + } + PythonSettings._() : super(); + factory PythonSettings.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + factory PythonSettings.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'PythonSettings', + package: const $pb.PackageName(_omitMessageNames ? '' : 'google.api'), + createEmptyInstance: create) + ..aOM<CommonLanguageSettings>(1, _omitFieldNames ? '' : 'common', + subBuilder: CommonLanguageSettings.create) + ..aOM<PythonSettings_ExperimentalFeatures>( + 2, _omitFieldNames ? '' : 'experimentalFeatures', + subBuilder: PythonSettings_ExperimentalFeatures.create) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + PythonSettings clone() => PythonSettings()..mergeFromMessage(this); + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + PythonSettings copyWith(void Function(PythonSettings) updates) => + super.copyWith((message) => updates(message as PythonSettings)) + as PythonSettings; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static PythonSettings create() => PythonSettings._(); + PythonSettings createEmptyInstance() => create(); + static $pb.PbList<PythonSettings> createRepeated() => + $pb.PbList<PythonSettings>(); + @$core.pragma('dart2js:noInline') + static PythonSettings getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor<PythonSettings>(create); + static PythonSettings? _defaultInstance; + + /// Some settings. + @$pb.TagNumber(1) + CommonLanguageSettings get common => $_getN(0); + @$pb.TagNumber(1) + set common(CommonLanguageSettings v) { + $_setField(1, v); + } + + @$pb.TagNumber(1) + $core.bool hasCommon() => $_has(0); + @$pb.TagNumber(1) + void clearCommon() => $_clearField(1); + @$pb.TagNumber(1) + CommonLanguageSettings ensureCommon() => $_ensure(0); + + /// Experimental features to be included during client library generation. + @$pb.TagNumber(2) + PythonSettings_ExperimentalFeatures get experimentalFeatures => $_getN(1); + @$pb.TagNumber(2) + set experimentalFeatures(PythonSettings_ExperimentalFeatures v) { + $_setField(2, v); + } + + @$pb.TagNumber(2) + $core.bool hasExperimentalFeatures() => $_has(1); + @$pb.TagNumber(2) + void clearExperimentalFeatures() => $_clearField(2); + @$pb.TagNumber(2) + PythonSettings_ExperimentalFeatures ensureExperimentalFeatures() => + $_ensure(1); +} + +/// Settings for Node client libraries. +class NodeSettings extends $pb.GeneratedMessage { + factory NodeSettings({ + CommonLanguageSettings? common, + }) { + final $result = create(); + if (common != null) { + $result.common = common; + } + return $result; + } + NodeSettings._() : super(); + factory NodeSettings.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + factory NodeSettings.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'NodeSettings', + package: const $pb.PackageName(_omitMessageNames ? '' : 'google.api'), + createEmptyInstance: create) + ..aOM<CommonLanguageSettings>(1, _omitFieldNames ? '' : 'common', + subBuilder: CommonLanguageSettings.create) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + NodeSettings clone() => NodeSettings()..mergeFromMessage(this); + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + NodeSettings copyWith(void Function(NodeSettings) updates) => + super.copyWith((message) => updates(message as NodeSettings)) + as NodeSettings; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static NodeSettings create() => NodeSettings._(); + NodeSettings createEmptyInstance() => create(); + static $pb.PbList<NodeSettings> createRepeated() => + $pb.PbList<NodeSettings>(); + @$core.pragma('dart2js:noInline') + static NodeSettings getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor<NodeSettings>(create); + static NodeSettings? _defaultInstance; + + /// Some settings. + @$pb.TagNumber(1) + CommonLanguageSettings get common => $_getN(0); + @$pb.TagNumber(1) + set common(CommonLanguageSettings v) { + $_setField(1, v); + } + + @$pb.TagNumber(1) + $core.bool hasCommon() => $_has(0); + @$pb.TagNumber(1) + void clearCommon() => $_clearField(1); + @$pb.TagNumber(1) + CommonLanguageSettings ensureCommon() => $_ensure(0); +} + +/// Settings for Dotnet client libraries. +class DotnetSettings extends $pb.GeneratedMessage { + factory DotnetSettings({ + CommonLanguageSettings? common, + $core.Iterable<$core.MapEntry<$core.String, $core.String>>? renamedServices, + $core.Iterable<$core.MapEntry<$core.String, $core.String>>? + renamedResources, + $core.Iterable<$core.String>? ignoredResources, + $core.Iterable<$core.String>? forcedNamespaceAliases, + $core.Iterable<$core.String>? handwrittenSignatures, + }) { + final $result = create(); + if (common != null) { + $result.common = common; + } + if (renamedServices != null) { + $result.renamedServices.addEntries(renamedServices); + } + if (renamedResources != null) { + $result.renamedResources.addEntries(renamedResources); + } + if (ignoredResources != null) { + $result.ignoredResources.addAll(ignoredResources); + } + if (forcedNamespaceAliases != null) { + $result.forcedNamespaceAliases.addAll(forcedNamespaceAliases); + } + if (handwrittenSignatures != null) { + $result.handwrittenSignatures.addAll(handwrittenSignatures); + } + return $result; + } + DotnetSettings._() : super(); + factory DotnetSettings.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + factory DotnetSettings.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'DotnetSettings', + package: const $pb.PackageName(_omitMessageNames ? '' : 'google.api'), + createEmptyInstance: create) + ..aOM<CommonLanguageSettings>(1, _omitFieldNames ? '' : 'common', + subBuilder: CommonLanguageSettings.create) + ..m<$core.String, $core.String>(2, _omitFieldNames ? '' : 'renamedServices', + entryClassName: 'DotnetSettings.RenamedServicesEntry', + keyFieldType: $pb.PbFieldType.OS, + valueFieldType: $pb.PbFieldType.OS, + packageName: const $pb.PackageName('google.api')) + ..m<$core.String, $core.String>( + 3, _omitFieldNames ? '' : 'renamedResources', + entryClassName: 'DotnetSettings.RenamedResourcesEntry', + keyFieldType: $pb.PbFieldType.OS, + valueFieldType: $pb.PbFieldType.OS, + packageName: const $pb.PackageName('google.api')) + ..pPS(4, _omitFieldNames ? '' : 'ignoredResources') + ..pPS(5, _omitFieldNames ? '' : 'forcedNamespaceAliases') + ..pPS(6, _omitFieldNames ? '' : 'handwrittenSignatures') + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + DotnetSettings clone() => DotnetSettings()..mergeFromMessage(this); + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + DotnetSettings copyWith(void Function(DotnetSettings) updates) => + super.copyWith((message) => updates(message as DotnetSettings)) + as DotnetSettings; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static DotnetSettings create() => DotnetSettings._(); + DotnetSettings createEmptyInstance() => create(); + static $pb.PbList<DotnetSettings> createRepeated() => + $pb.PbList<DotnetSettings>(); + @$core.pragma('dart2js:noInline') + static DotnetSettings getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor<DotnetSettings>(create); + static DotnetSettings? _defaultInstance; + + /// Some settings. + @$pb.TagNumber(1) + CommonLanguageSettings get common => $_getN(0); + @$pb.TagNumber(1) + set common(CommonLanguageSettings v) { + $_setField(1, v); + } + + @$pb.TagNumber(1) + $core.bool hasCommon() => $_has(0); + @$pb.TagNumber(1) + void clearCommon() => $_clearField(1); + @$pb.TagNumber(1) + CommonLanguageSettings ensureCommon() => $_ensure(0); + + /// Map from original service names to renamed versions. + /// This is used when the default generated types + /// would cause a naming conflict. (Neither name is + /// fully-qualified.) + /// Example: Subscriber to SubscriberServiceApi. + @$pb.TagNumber(2) + $pb.PbMap<$core.String, $core.String> get renamedServices => $_getMap(1); + + /// Map from full resource types to the effective short name + /// for the resource. This is used when otherwise resource + /// named from different services would cause naming collisions. + /// Example entry: + /// "datalabeling.googleapis.com/Dataset": "DataLabelingDataset" + @$pb.TagNumber(3) + $pb.PbMap<$core.String, $core.String> get renamedResources => $_getMap(2); + + /// List of full resource types to ignore during generation. + /// This is typically used for API-specific Location resources, + /// which should be handled by the generator as if they were actually + /// the common Location resources. + /// Example entry: "documentai.googleapis.com/Location" + @$pb.TagNumber(4) + $pb.PbList<$core.String> get ignoredResources => $_getList(3); + + /// Namespaces which must be aliased in snippets due to + /// a known (but non-generator-predictable) naming collision + @$pb.TagNumber(5) + $pb.PbList<$core.String> get forcedNamespaceAliases => $_getList(4); + + /// Method signatures (in the form "service.method(signature)") + /// which are provided separately, so shouldn't be generated. + /// Snippets *calling* these methods are still generated, however. + @$pb.TagNumber(6) + $pb.PbList<$core.String> get handwrittenSignatures => $_getList(5); +} + +/// Settings for Ruby client libraries. +class RubySettings extends $pb.GeneratedMessage { + factory RubySettings({ + CommonLanguageSettings? common, + }) { + final $result = create(); + if (common != null) { + $result.common = common; + } + return $result; + } + RubySettings._() : super(); + factory RubySettings.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + factory RubySettings.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'RubySettings', + package: const $pb.PackageName(_omitMessageNames ? '' : 'google.api'), + createEmptyInstance: create) + ..aOM<CommonLanguageSettings>(1, _omitFieldNames ? '' : 'common', + subBuilder: CommonLanguageSettings.create) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + RubySettings clone() => RubySettings()..mergeFromMessage(this); + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RubySettings copyWith(void Function(RubySettings) updates) => + super.copyWith((message) => updates(message as RubySettings)) + as RubySettings; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static RubySettings create() => RubySettings._(); + RubySettings createEmptyInstance() => create(); + static $pb.PbList<RubySettings> createRepeated() => + $pb.PbList<RubySettings>(); + @$core.pragma('dart2js:noInline') + static RubySettings getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor<RubySettings>(create); + static RubySettings? _defaultInstance; + + /// Some settings. + @$pb.TagNumber(1) + CommonLanguageSettings get common => $_getN(0); + @$pb.TagNumber(1) + set common(CommonLanguageSettings v) { + $_setField(1, v); + } + + @$pb.TagNumber(1) + $core.bool hasCommon() => $_has(0); + @$pb.TagNumber(1) + void clearCommon() => $_clearField(1); + @$pb.TagNumber(1) + CommonLanguageSettings ensureCommon() => $_ensure(0); +} + +/// Settings for Go client libraries. +class GoSettings extends $pb.GeneratedMessage { + factory GoSettings({ + CommonLanguageSettings? common, + $core.Iterable<$core.MapEntry<$core.String, $core.String>>? renamedServices, + }) { + final $result = create(); + if (common != null) { + $result.common = common; + } + if (renamedServices != null) { + $result.renamedServices.addEntries(renamedServices); + } + return $result; + } + GoSettings._() : super(); + factory GoSettings.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + factory GoSettings.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'GoSettings', + package: const $pb.PackageName(_omitMessageNames ? '' : 'google.api'), + createEmptyInstance: create) + ..aOM<CommonLanguageSettings>(1, _omitFieldNames ? '' : 'common', + subBuilder: CommonLanguageSettings.create) + ..m<$core.String, $core.String>(2, _omitFieldNames ? '' : 'renamedServices', + entryClassName: 'GoSettings.RenamedServicesEntry', + keyFieldType: $pb.PbFieldType.OS, + valueFieldType: $pb.PbFieldType.OS, + packageName: const $pb.PackageName('google.api')) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + GoSettings clone() => GoSettings()..mergeFromMessage(this); + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + GoSettings copyWith(void Function(GoSettings) updates) => + super.copyWith((message) => updates(message as GoSettings)) as GoSettings; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static GoSettings create() => GoSettings._(); + GoSettings createEmptyInstance() => create(); + static $pb.PbList<GoSettings> createRepeated() => $pb.PbList<GoSettings>(); + @$core.pragma('dart2js:noInline') + static GoSettings getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor<GoSettings>(create); + static GoSettings? _defaultInstance; + + /// Some settings. + @$pb.TagNumber(1) + CommonLanguageSettings get common => $_getN(0); + @$pb.TagNumber(1) + set common(CommonLanguageSettings v) { + $_setField(1, v); + } + + @$pb.TagNumber(1) + $core.bool hasCommon() => $_has(0); + @$pb.TagNumber(1) + void clearCommon() => $_clearField(1); + @$pb.TagNumber(1) + CommonLanguageSettings ensureCommon() => $_ensure(0); + + /// Map of service names to renamed services. Keys are the package relative + /// service names and values are the name to be used for the service client + /// and call options. + /// + /// publishing: + /// go_settings: + /// renamed_services: + /// Publisher: TopicAdmin + @$pb.TagNumber(2) + $pb.PbMap<$core.String, $core.String> get renamedServices => $_getMap(1); +} + +/// This message is used to configure the generation of a subset of the RPCs in +/// a service for client libraries. +class SelectiveGapicGeneration extends $pb.GeneratedMessage { + factory SelectiveGapicGeneration({ + $core.Iterable<$core.String>? methods, + $core.bool? generateOmittedAsInternal, + }) { + final $result = create(); + if (methods != null) { + $result.methods.addAll(methods); + } + if (generateOmittedAsInternal != null) { + $result.generateOmittedAsInternal = generateOmittedAsInternal; + } + return $result; + } + SelectiveGapicGeneration._() : super(); + factory SelectiveGapicGeneration.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + factory SelectiveGapicGeneration.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'SelectiveGapicGeneration', + package: const $pb.PackageName(_omitMessageNames ? '' : 'google.api'), + createEmptyInstance: create) + ..pPS(1, _omitFieldNames ? '' : 'methods') + ..aOB(2, _omitFieldNames ? '' : 'generateOmittedAsInternal') + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + SelectiveGapicGeneration clone() => + SelectiveGapicGeneration()..mergeFromMessage(this); + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + SelectiveGapicGeneration copyWith( + void Function(SelectiveGapicGeneration) updates) => + super.copyWith((message) => updates(message as SelectiveGapicGeneration)) + as SelectiveGapicGeneration; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static SelectiveGapicGeneration create() => SelectiveGapicGeneration._(); + SelectiveGapicGeneration createEmptyInstance() => create(); + static $pb.PbList<SelectiveGapicGeneration> createRepeated() => + $pb.PbList<SelectiveGapicGeneration>(); + @$core.pragma('dart2js:noInline') + static SelectiveGapicGeneration getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor<SelectiveGapicGeneration>(create); + static SelectiveGapicGeneration? _defaultInstance; + + /// An allowlist of the fully qualified names of RPCs that should be included + /// on public client surfaces. + @$pb.TagNumber(1) + $pb.PbList<$core.String> get methods => $_getList(0); + + /// Setting this to true indicates to the client generators that methods + /// that would be excluded from the generation should instead be generated + /// in a way that indicates these methods should not be consumed by + /// end users. How this is expressed is up to individual language + /// implementations to decide. Some examples may be: added annotations, + /// obfuscated identifiers, or other language idiomatic patterns. + @$pb.TagNumber(2) + $core.bool get generateOmittedAsInternal => $_getBF(1); + @$pb.TagNumber(2) + set generateOmittedAsInternal($core.bool v) { + $_setBool(1, v); + } + + @$pb.TagNumber(2) + $core.bool hasGenerateOmittedAsInternal() => $_has(1); + @$pb.TagNumber(2) + void clearGenerateOmittedAsInternal() => $_clearField(2); +} + +class Client { + static final methodSignature = $pb.Extension<$core.String>.repeated( + _omitMessageNames ? '' : 'google.protobuf.MethodOptions', + _omitFieldNames ? '' : 'methodSignature', + 1051, + $pb.PbFieldType.PS, + check: $pb.getCheckFunction($pb.PbFieldType.PS)); + static final defaultHost = $pb.Extension<$core.String>( + _omitMessageNames ? '' : 'google.protobuf.ServiceOptions', + _omitFieldNames ? '' : 'defaultHost', + 1049, + $pb.PbFieldType.OS); + static final oauthScopes = $pb.Extension<$core.String>( + _omitMessageNames ? '' : 'google.protobuf.ServiceOptions', + _omitFieldNames ? '' : 'oauthScopes', + 1050, + $pb.PbFieldType.OS); + static final apiVersion = $pb.Extension<$core.String>( + _omitMessageNames ? '' : 'google.protobuf.ServiceOptions', + _omitFieldNames ? '' : 'apiVersion', + 525000001, + $pb.PbFieldType.OS); + static void registerAllExtensions($pb.ExtensionRegistry registry) { + registry.add(methodSignature); + registry.add(defaultHost); + registry.add(oauthScopes); + registry.add(apiVersion); + } +} + +const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names'); +const _omitMessageNames = + $core.bool.fromEnvironment('protobuf.omit_message_names');
diff --git a/protoc_plugin/lib/src/generated/client.pbenum.dart b/protoc_plugin/lib/src/generated/client.pbenum.dart new file mode 100644 index 0000000..bc568da --- /dev/null +++ b/protoc_plugin/lib/src/generated/client.pbenum.dart
@@ -0,0 +1,103 @@ +// +// Generated code. Do not modify. +// source: client.proto +// +// @dart = 3.3 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +/// The organization for which the client libraries are being published. +/// Affects the url where generated docs are published, etc. +class ClientLibraryOrganization extends $pb.ProtobufEnum { + /// Not useful. + static const ClientLibraryOrganization + CLIENT_LIBRARY_ORGANIZATION_UNSPECIFIED = ClientLibraryOrganization._( + 0, _omitEnumNames ? '' : 'CLIENT_LIBRARY_ORGANIZATION_UNSPECIFIED'); + + /// Google Cloud Platform Org. + static const ClientLibraryOrganization CLOUD = + ClientLibraryOrganization._(1, _omitEnumNames ? '' : 'CLOUD'); + + /// Ads (Advertising) Org. + static const ClientLibraryOrganization ADS = + ClientLibraryOrganization._(2, _omitEnumNames ? '' : 'ADS'); + + /// Photos Org. + static const ClientLibraryOrganization PHOTOS = + ClientLibraryOrganization._(3, _omitEnumNames ? '' : 'PHOTOS'); + + /// Street View Org. + static const ClientLibraryOrganization STREET_VIEW = + ClientLibraryOrganization._(4, _omitEnumNames ? '' : 'STREET_VIEW'); + + /// Shopping Org. + static const ClientLibraryOrganization SHOPPING = + ClientLibraryOrganization._(5, _omitEnumNames ? '' : 'SHOPPING'); + + /// Geo Org. + static const ClientLibraryOrganization GEO = + ClientLibraryOrganization._(6, _omitEnumNames ? '' : 'GEO'); + + /// Generative AI - https://developers.generativeai.google + static const ClientLibraryOrganization GENERATIVE_AI = + ClientLibraryOrganization._(7, _omitEnumNames ? '' : 'GENERATIVE_AI'); + + static const $core.List<ClientLibraryOrganization> values = + <ClientLibraryOrganization>[ + CLIENT_LIBRARY_ORGANIZATION_UNSPECIFIED, + CLOUD, + ADS, + PHOTOS, + STREET_VIEW, + SHOPPING, + GEO, + GENERATIVE_AI, + ]; + + static final $core.List<ClientLibraryOrganization?> _byValue = + $pb.ProtobufEnum.$_initByValueList(values, 7); + static ClientLibraryOrganization? valueOf($core.int value) => + value < 0 || value >= _byValue.length ? null : _byValue[value]; + + const ClientLibraryOrganization._(super.v, super.n); +} + +/// To where should client libraries be published? +class ClientLibraryDestination extends $pb.ProtobufEnum { + /// Client libraries will neither be generated nor published to package + /// managers. + static const ClientLibraryDestination CLIENT_LIBRARY_DESTINATION_UNSPECIFIED = + ClientLibraryDestination._( + 0, _omitEnumNames ? '' : 'CLIENT_LIBRARY_DESTINATION_UNSPECIFIED'); + + /// Generate the client library in a repo under github.com/googleapis, + /// but don't publish it to package managers. + static const ClientLibraryDestination GITHUB = + ClientLibraryDestination._(10, _omitEnumNames ? '' : 'GITHUB'); + + /// Publish the library to package managers like nuget.org and npmjs.com. + static const ClientLibraryDestination PACKAGE_MANAGER = + ClientLibraryDestination._(20, _omitEnumNames ? '' : 'PACKAGE_MANAGER'); + + static const $core.List<ClientLibraryDestination> values = + <ClientLibraryDestination>[ + CLIENT_LIBRARY_DESTINATION_UNSPECIFIED, + GITHUB, + PACKAGE_MANAGER, + ]; + + static final $core.Map<$core.int, ClientLibraryDestination> _byValue = + $pb.ProtobufEnum.initByValue(values); + static ClientLibraryDestination? valueOf($core.int value) => _byValue[value]; + + const ClientLibraryDestination._(super.v, super.n); +} + +const _omitEnumNames = $core.bool.fromEnvironment('protobuf.omit_enum_names');
diff --git a/protoc_plugin/lib/src/grpc_generator.dart b/protoc_plugin/lib/src/grpc_generator.dart index 85ad5e9..b7b3784 100644 --- a/protoc_plugin/lib/src/grpc_generator.dart +++ b/protoc_plugin/lib/src/grpc_generator.dart
@@ -124,6 +124,26 @@ } out.println("@$protobufImportPrefix.GrpcServiceName('$_fullServiceName')"); out.addBlock('class $_clientClassname extends $_client {', '}', () { + // Look for and generate default_host info. + final defaultHost = _descriptor.options.defaultHost; + if (defaultHost != null) { + out.println('/// The hostname for this service.'); + out.println("static const $_string defaultHost = '$defaultHost';"); + out.println(); + } + + // Look for and generate oauth_scopes info. + final oauthScopes = _descriptor.options.oauthScopes; + if (oauthScopes != null) { + out.println('/// OAuth scopes needed for the client.'); + out.println('static const $_list<$_string> oauthScopes = ['); + for (final scope in oauthScopes.split(',')) { + out.println(" '$scope',"); + } + out.println('];'); + out.println(); + } + for (final method in _methods) { method.generateClientMethodDescriptor(out); } @@ -161,6 +181,8 @@ static final String _callOptions = '$grpcImportPrefix.CallOptions'; static final String _client = '$grpcImportPrefix.Client'; static final String _service = '$grpcImportPrefix.Service'; + static final String _list = '$coreImportPrefix.List'; + static final String _string = '$coreImportPrefix.String'; } class _GrpcMethod { @@ -318,3 +340,9 @@ static final String _responseFuture = '$grpcImportPrefix.ResponseFuture'; static final String _responseStream = '$grpcImportPrefix.ResponseStream'; } + +extension on ServiceOptions { + String? get defaultHost => getExtension(Client.defaultHost) as String?; + + String? get oauthScopes => getExtension(Client.oauthScopes) as String?; +}
diff --git a/protoc_plugin/protos/client.proto b/protoc_plugin/protos/client.proto new file mode 100644 index 0000000..0991b2d --- /dev/null +++ b/protoc_plugin/protos/client.proto
@@ -0,0 +1,369 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "descriptor.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "ClientProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +extend google.protobuf.MethodOptions { + // A definition of a client library method signature. + // + // In client libraries, each proto RPC corresponds to one or more methods + // which the end user is able to call, and calls the underlying RPC. + // Normally, this method receives a single argument (a struct or instance + // corresponding to the RPC request object). Defining this field will + // add one or more overloads providing flattened or simpler method signatures + // in some languages. + // + // The fields on the method signature are provided as a comma-separated + // string. + // + // For example, the proto RPC and annotation: + // + // rpc CreateSubscription(CreateSubscriptionRequest) + // returns (Subscription) { + // option (google.api.method_signature) = "name,topic"; + // } + // + // Would add the following Java overload (in addition to the method accepting + // the request object): + // + // public final Subscription createSubscription(String name, String topic) + // + // The following backwards-compatibility guidelines apply: + // + // * Adding this annotation to an unannotated method is backwards + // compatible. + // * Adding this annotation to a method which already has existing + // method signature annotations is backwards compatible if and only if + // the new method signature annotation is last in the sequence. + // * Modifying or removing an existing method signature annotation is + // a breaking change. + // * Re-ordering existing method signature annotations is a breaking + // change. + repeated string method_signature = 1051; +} + +extend google.protobuf.ServiceOptions { + // The hostname for this service. + // This should be specified with no prefix or protocol. + // + // Example: + // + // service Foo { + // option (google.api.default_host) = "foo.googleapi.com"; + // ... + // } + string default_host = 1049; + + // OAuth scopes needed for the client. + // + // Example: + // + // service Foo { + // option (google.api.oauth_scopes) = \ + // "https://www.googleapis.com/auth/cloud-platform"; + // ... + // } + // + // If there is more than one scope, use a comma-separated string: + // + // Example: + // + // service Foo { + // option (google.api.oauth_scopes) = \ + // "https://www.googleapis.com/auth/cloud-platform," + // "https://www.googleapis.com/auth/monitoring"; + // ... + // } + string oauth_scopes = 1050; + + // The API version of this service, which should be sent by version-aware + // clients to the service. This allows services to abide by the schema and + // behavior of the service at the time this API version was deployed. + // The format of the API version must be treated as opaque by clients. + // Services may use a format with an apparent structure, but clients must + // not rely on this to determine components within an API version, or attempt + // to construct other valid API versions. Note that this is for upcoming + // functionality and may not be implemented for all services. + // + // Example: + // + // service Foo { + // option (google.api.api_version) = "v1_20230821_preview"; + // } + string api_version = 525000001; +} + +// Required information for every language. +message CommonLanguageSettings { + // Link to automatically generated reference documentation. Example: + // https://cloud.google.com/nodejs/docs/reference/asset/latest + string reference_docs_uri = 1 [deprecated = true]; + + // The destination where API teams want this client library to be published. + repeated ClientLibraryDestination destinations = 2; + + // Configuration for which RPCs should be generated in the GAPIC client. + SelectiveGapicGeneration selective_gapic_generation = 3; +} + +// This message configures the settings for publishing [Google Cloud Client +// libraries](https://cloud.google.com/apis/docs/cloud-client-libraries) +// generated from the service config. +message Publishing { + // Link to a *public* URI where users can report issues. Example: + // https://issuetracker.google.com/issues/new?component=190865&template=1161103 + string new_issue_uri = 101; + + // Link to product home page. Example: + // https://cloud.google.com/asset-inventory/docs/overview + string documentation_uri = 102; + + // Used as a tracking tag when collecting data about the APIs developer + // relations artifacts like docs, packages delivered to package managers, + // etc. Example: "speech". + string api_short_name = 103; + + // GitHub label to apply to issues and pull requests opened for this API. + string github_label = 104; + + // GitHub teams to be added to CODEOWNERS in the directory in GitHub + // containing source code for the client libraries for this API. + repeated string codeowner_github_teams = 105; + + // A prefix used in sample code when demarking regions to be included in + // documentation. + string doc_tag_prefix = 106; + + // For whom the client library is being published. + ClientLibraryOrganization organization = 107; + + // Optional link to proto reference documentation. Example: + // https://cloud.google.com/pubsub/lite/docs/reference/rpc + string proto_reference_documentation_uri = 110; + + // Optional link to REST reference documentation. Example: + // https://cloud.google.com/pubsub/lite/docs/reference/rest + string rest_reference_documentation_uri = 111; +} + +// Settings for Java client libraries. +message JavaSettings { + // The package name to use in Java. Clobbers the java_package option + // set in the protobuf. This should be used **only** by APIs + // who have already set the language_settings.java.package_name" field + // in gapic.yaml. API teams should use the protobuf java_package option + // where possible. + // + // Example of a YAML configuration:: + // + // publishing: + // java_settings: + // library_package: com.google.cloud.pubsub.v1 + string library_package = 1; + + // Configure the Java class name to use instead of the service's for its + // corresponding generated GAPIC client. Keys are fully-qualified + // service names as they appear in the protobuf (including the full + // the language_settings.java.interface_names" field in gapic.yaml. API + // teams should otherwise use the service name as it appears in the + // protobuf. + // + // Example of a YAML configuration:: + // + // publishing: + // java_settings: + // service_class_names: + // - google.pubsub.v1.Publisher: TopicAdmin + // - google.pubsub.v1.Subscriber: SubscriptionAdmin + map<string, string> service_class_names = 2; + + // Some settings. + CommonLanguageSettings common = 3; +} + +// Settings for C++ client libraries. +message CppSettings { + // Some settings. + CommonLanguageSettings common = 1; +} + +// Settings for Php client libraries. +message PhpSettings { + // Some settings. + CommonLanguageSettings common = 1; +} + +// Settings for Python client libraries. +message PythonSettings { + // Experimental features to be included during client library generation. + // These fields will be deprecated once the feature graduates and is enabled + // by default. + message ExperimentalFeatures { + // Enables generation of asynchronous REST clients if `rest` transport is + // enabled. By default, asynchronous REST clients will not be generated. + // This feature will be enabled by default 1 month after launching the + // feature in preview packages. + bool rest_async_io_enabled = 1; + + // Enables generation of protobuf code using new types that are more + // Pythonic which are included in `protobuf>=5.29.x`. This feature will be + // enabled by default 1 month after launching the feature in preview + // packages. + bool protobuf_pythonic_types_enabled = 2; + + // Disables generation of an unversioned Python package for this client + // library. This means that the module names will need to be versioned in + // import statements. For example `import google.cloud.library_v2` instead + // of `import google.cloud.library`. + bool unversioned_package_disabled = 3; + } + + // Some settings. + CommonLanguageSettings common = 1; + + // Experimental features to be included during client library generation. + ExperimentalFeatures experimental_features = 2; +} + +// Settings for Node client libraries. +message NodeSettings { + // Some settings. + CommonLanguageSettings common = 1; +} + +// Settings for Dotnet client libraries. +message DotnetSettings { + // Some settings. + CommonLanguageSettings common = 1; + + // Map from original service names to renamed versions. + // This is used when the default generated types + // would cause a naming conflict. (Neither name is + // fully-qualified.) + // Example: Subscriber to SubscriberServiceApi. + map<string, string> renamed_services = 2; + + // Map from full resource types to the effective short name + // for the resource. This is used when otherwise resource + // named from different services would cause naming collisions. + // Example entry: + // "datalabeling.googleapis.com/Dataset": "DataLabelingDataset" + map<string, string> renamed_resources = 3; + + // List of full resource types to ignore during generation. + // This is typically used for API-specific Location resources, + // which should be handled by the generator as if they were actually + // the common Location resources. + // Example entry: "documentai.googleapis.com/Location" + repeated string ignored_resources = 4; + + // Namespaces which must be aliased in snippets due to + // a known (but non-generator-predictable) naming collision + repeated string forced_namespace_aliases = 5; + + // Method signatures (in the form "service.method(signature)") + // which are provided separately, so shouldn't be generated. + // Snippets *calling* these methods are still generated, however. + repeated string handwritten_signatures = 6; +} + +// Settings for Ruby client libraries. +message RubySettings { + // Some settings. + CommonLanguageSettings common = 1; +} + +// Settings for Go client libraries. +message GoSettings { + // Some settings. + CommonLanguageSettings common = 1; + + // Map of service names to renamed services. Keys are the package relative + // service names and values are the name to be used for the service client + // and call options. + // + // publishing: + // go_settings: + // renamed_services: + // Publisher: TopicAdmin + map<string, string> renamed_services = 2; +} + +// The organization for which the client libraries are being published. +// Affects the url where generated docs are published, etc. +enum ClientLibraryOrganization { + // Not useful. + CLIENT_LIBRARY_ORGANIZATION_UNSPECIFIED = 0; + + // Google Cloud Platform Org. + CLOUD = 1; + + // Ads (Advertising) Org. + ADS = 2; + + // Photos Org. + PHOTOS = 3; + + // Street View Org. + STREET_VIEW = 4; + + // Shopping Org. + SHOPPING = 5; + + // Geo Org. + GEO = 6; + + // Generative AI - https://developers.generativeai.google + GENERATIVE_AI = 7; +} + +// To where should client libraries be published? +enum ClientLibraryDestination { + // Client libraries will neither be generated nor published to package + // managers. + CLIENT_LIBRARY_DESTINATION_UNSPECIFIED = 0; + + // Generate the client library in a repo under github.com/googleapis, + // but don't publish it to package managers. + GITHUB = 10; + + // Publish the library to package managers like nuget.org and npmjs.com. + PACKAGE_MANAGER = 20; +} + +// This message is used to configure the generation of a subset of the RPCs in +// a service for client libraries. +message SelectiveGapicGeneration { + // An allowlist of the fully qualified names of RPCs that should be included + // on public client surfaces. + repeated string methods = 1; + + // Setting this to true indicates to the client generators that methods + // that would be excluded from the generation should instead be generated + // in a way that indicates these methods should not be consumed by + // end users. How this is expressed is up to individual language + // implementations to decide. Some examples may be: added annotations, + // obfuscated identifiers, or other language idiomatic patterns. + bool generate_omitted_as_internal = 2; +}
diff --git a/protoc_plugin/pubspec.yaml b/protoc_plugin/pubspec.yaml index c1c12a2..a1070de 100644 --- a/protoc_plugin/pubspec.yaml +++ b/protoc_plugin/pubspec.yaml
@@ -1,5 +1,5 @@ name: protoc_plugin -version: 22.1.1-wip +version: 22.2.0 description: A protobuf protoc compiler plugin used to generate Dart code. repository: https://github.com/google/protobuf.dart/tree/master/protoc_plugin
diff --git a/protoc_plugin/test/file_generator_test.dart b/protoc_plugin/test/file_generator_test.dart index f248e8a..26a297d 100644 --- a/protoc_plugin/test/file_generator_test.dart +++ b/protoc_plugin/test/file_generator_test.dart
@@ -4,6 +4,7 @@ import 'package:protoc_plugin/indenting_writer.dart'; import 'package:protoc_plugin/protoc.dart'; +import 'package:protoc_plugin/src/generated/client.pb.dart'; import 'package:protoc_plugin/src/generated/descriptor.pb.dart'; import 'package:protoc_plugin/src/generated/plugin.pb.dart'; import 'package:protoc_plugin/src/linker.dart'; @@ -328,8 +329,17 @@ ..clientStreaming = false ..serverStreaming = false; + final serviceOptions = ServiceOptions(); + serviceOptions.setExtension(Client.defaultHost, 'www.example.com'); + serviceOptions.setExtension( + Client.oauthScopes, + 'https://www.googleapis.com/auth/cloud-platform,' + 'https://www.googleapis.com/auth/datastore', + ); + final sd = ServiceDescriptorProto() ..name = 'Test' + ..options = serviceOptions ..method.addAll([ unary, clientStreaming,
diff --git a/protoc_plugin/test/goldens/grpc_service.pbgrpc b/protoc_plugin/test/goldens/grpc_service.pbgrpc index 2d6d5a2..eb99c20 100644 --- a/protoc_plugin/test/goldens/grpc_service.pbgrpc +++ b/protoc_plugin/test/goldens/grpc_service.pbgrpc
@@ -21,6 +21,15 @@ @$pb.GrpcServiceName('Test') class TestClient extends $grpc.Client { + /// The hostname for this service. + static const $core.String defaultHost = 'www.example.com'; + + /// OAuth scopes needed for the client. + static const $core.List<$core.String> oauthScopes = [ + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/datastore', + ]; + static final _$unary = $grpc.ClientMethod<$0.Input, $0.Output>( '/Test/Unary', ($0.Input value) => value.writeToBuffer(),