diff --git a/gapic/samplegen_utils/snippet_index.py b/gapic/samplegen_utils/snippet_index.py new file mode 100644 index 0000000000..a8594a92ee --- /dev/null +++ b/gapic/samplegen_utils/snippet_index.py @@ -0,0 +1,175 @@ +# Copyright 2022 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. + +from typing import Optional, Dict +import re + +from google.protobuf import json_format + +from gapic.schema import api, metadata +from gapic.samplegen_utils import snippet_metadata_pb2 # type: ignore +from gapic.samplegen_utils import types + + +CLIENT_INIT_RE = re.compile(r"^\s+# Create a client") +REQUEST_INIT_RE = re.compile(r"^\s+# Initialize request argument\(s\)") +REQUEST_EXEC_RE = re.compile(r"^\s+# Make the request") +RESPONSE_HANDLING_RE = re.compile(r"^\s+# Handle response") + + +class Snippet: + """A single snippet and its metadata. + + Attributes: + sample_str (str): The full text of the code snippet. + metadata (snippet_metadata_pb2.Snippet): The snippet's metadata. + """ + + def __init__(self, sample_str: str, sample_metadata): + self.sample_str = sample_str + self.metadata = sample_metadata + self._parse_snippet_segments() + + def _parse_snippet_segments(self): + """Parse sections of the sample string and update metadata""" + self.sample_lines = self.sample_str.splitlines(keepends=True) + + self._full_snippet = snippet_metadata_pb2.Snippet.Segment( + type=snippet_metadata_pb2.Snippet.Segment.SegmentType.FULL) + self._short_snippet = snippet_metadata_pb2.Snippet.Segment( + type=snippet_metadata_pb2.Snippet.Segment.SegmentType.SHORT) + self._client_init = snippet_metadata_pb2.Snippet.Segment( + type=snippet_metadata_pb2.Snippet.Segment.SegmentType.CLIENT_INITIALIZATION) + self._request_init = snippet_metadata_pb2.Snippet.Segment( + type=snippet_metadata_pb2.Snippet.Segment.SegmentType.REQUEST_INITIALIZATION) + self._request_exec = snippet_metadata_pb2.Snippet.Segment( + type=snippet_metadata_pb2.Snippet.Segment.SegmentType.REQUEST_EXECUTION) + self._response_handling = snippet_metadata_pb2.Snippet.Segment( + type=snippet_metadata_pb2.Snippet.Segment.SegmentType.RESPONSE_HANDLING, + end=len(self.sample_lines) + ) + + # Index starts at 1 since these represent line numbers + for i, line in enumerate(self.sample_lines, start=1): + if line.startswith("# [START"): # do not include region tag lines + self._full_snippet.start = i + 1 + self._short_snippet.start = self._full_snippet.start + elif line.startswith("# [END"): + self._full_snippet.end = i - 1 + self._short_snippet.end = self._full_snippet.end + elif CLIENT_INIT_RE.match(line): + self._client_init.start = i + elif REQUEST_INIT_RE.match(line): + self._client_init.end = i - 1 + self._request_init.start = i + elif REQUEST_EXEC_RE.match(line): + self._request_init.end = i - 1 + self._request_exec.start = i + elif RESPONSE_HANDLING_RE.match(line): + self._request_exec.end = i - 1 + self._response_handling.start = i + + self.metadata.segments.extend([self._full_snippet, self._short_snippet, self._client_init, + self._request_init, self._request_exec, self._response_handling]) + + @property + def full_snippet(self) -> str: + """The portion between the START and END region tags.""" + start_idx = self._full_snippet.start - 1 + end_idx = self._full_snippet.end + return "".join(self.sample_lines[start_idx:end_idx]) + + +class SnippetIndex: + """An index of all the snippets for an API. + + Attributes: + metadata_index (snippet_metadata_pb2.Index): The snippet metadata index. + """ + + def __init__(self, api_schema: api.API): + self.metadata_index = snippet_metadata_pb2.Index() # type: ignore + + # Construct a dictionary to insert samples into based on the API schema + # NOTE: In the future we expect the generator to support configured samples, + # which will result in more than one sample variant per RPC. At that + # time a different data structure (and re-writes of add_snippet and get_snippet) + # will be needed. + self._index: Dict[str, Dict[str, Dict[str, Optional[Snippet]]]] = {} + + self._index = { + s.name: {m: {"sync": None, "async": None} for m in s.methods} + for s in api_schema.services.values() + } + + def add_snippet(self, snippet: Snippet) -> None: + """Add a single snippet to the snippet index. + + Args: + snippet (Snippet): The code snippet to be added. + + Raises: + UnknownService: If the service indicated by the snippet metadata is not found. + RpcMethodNotFound: If the method indicated by the snippet metadata is not found. + """ + service_name = snippet.metadata.client_method.method.service.short_name + rpc_name = snippet.metadata.client_method.method.full_name + + service = self._index.get(service_name) + if service is None: + raise types.UnknownService( + "API does not have a service named '{}'.".format(service_name)) + + method = service.get(rpc_name) + if method is None: + raise types.RpcMethodNotFound( + "API does not have method '{}' in service '{}'".format(rpc_name, service_name)) + + if getattr(snippet.metadata.client_method, "async"): + method["async"] = snippet + else: + method["sync"] = snippet + + self.metadata_index.snippets.append(snippet.metadata) + + def get_snippet(self, service_name: str, rpc_name: str, sync: bool = True) -> Optional[Snippet]: + """Fetch a single snippet from the index. + + Args: + service_name (str): The name of the service. + rpc_name (str): The name of the RPC. + sync (bool): True for the sync version of the snippet, False for the async version. + + Returns: + Optional[Snippet]: The snippet if it exists, or None. + + Raises: + UnknownService: If the service is not found. + RpcMethodNotFound: If the method is not found. + """ + # Fetch a snippet from the snippet metadata index + service = self._index.get(service_name) + if service is None: + raise types.UnknownService( + "API does not have a service named '{}'.".format(service_name)) + method = service.get(rpc_name) + if method is None: + raise types.RpcMethodNotFound( + "API does not have method '{}' in service '{}'".format(rpc_name, service_name)) + + return method["sync" if sync else "async"] + + def get_metadata_json(self) -> str: + """JSON representation of Snippet Index.""" + return json_format.MessageToJson(self.metadata_index, sort_keys=True) diff --git a/gapic/samplegen_utils/snippet_metadata.proto b/gapic/samplegen_utils/snippet_metadata.proto new file mode 100644 index 0000000000..398dc9b27c --- /dev/null +++ b/gapic/samplegen_utils/snippet_metadata.proto @@ -0,0 +1,319 @@ +// Copyright 2021 Google Inc. All Rights Reserved. +// +// 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 +// +// https://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. + +// NOTE(busunkim): This is a temporary home for this file and the corresponding +// snippet_metadata_pb2.py. + +syntax = "proto3"; + +package google.cloud.tools.snippetgen.snippetindex.v1; + +option csharp_namespace = "Google.Cloud.Tools.SnippetGen.SnippetIndex.V1"; +option php_namespace = "Google\\Cloud\\Tools\\SnippetGen\\SnippetIndex\\V1"; +option ruby_package = "Google::Cloud::Tools::SnippetGen::SnippetIndex::V1"; + +// The snippet index for a single client library. +message Index { + // The Client Library these snippets are for. + ClientLibrary client_library = 1; + + // The list of snippets. + repeated Snippet snippets = 2; +} + +// One sample. +// Parts of this information will be language specific. +message Snippet { + // The region tag name. Does not include the square brackets or the START or + // END indicators. + string region_tag = 1; + + // The title of the snippet, for human consumption mostly. For generated + // snippets this may be the snippet method or file name, or obtained from + /// snippet configuration. + string title = 2; + + // A description of the snippet, for human consumption mostly. For generated + // snippets this may be the description of the service method, or obtained + // from snippet configuration. + string description = 3; + + // The file where the snippet code lives. + // The path should be relative to where this metadata file is stored on the + // GitHub repo root and should not include branch, tag, commitish, etc., + // as those will be the same as for the metadata file. + string file = 4; + + // The programming language the snippet is written in. + // This will match the client library language most of the time, but not + // always. For instance, in .NET, libraries are written in C# but some samples + // may be written in F# or VB .NET. + // Note that this does not contain information about the snippet supported + // platforms or language versions, etc. This is just a quick way to identify + // the generally supported langauge. + Language language = 5; + + // The client library method this snippet is for. + ClientMethod client_method = 6; + + // Wether this is the canonical snippet for the corresponding service method. + // This is to be interpreted in conjunction with origin as follows: + // For a given service method: + // - A handwritten canonical takes precedence over + // - A config canonical which in turn takes precedence over + // - A baseline canonical. + bool canonical = 7; + + // The origin of the snippet. + Origin origin = 8; + + // The different segments of the snippet. + // Must contain the FULL segment always. + // There may be overlap between segments. + repeated Segment segments = 9; + + // The origin of the snippet. + enum Origin { + // The origin has not been specified. Consumers should not see this value. + ORIGIN_UNSPECIFIED = 0; + + // The snippet is generated from the API definition only, including protos + // and descriptive information, i.e. the same information used to generate + // the client libraries themselves. + // No snippet configuration has been specified. This refers to SnippetGen + // phase 1. + API_DEFINITION = 1; + + // The snippet is generated from the API definition and a specific snippet + // configuration. This refers to SnippetGen phase 2. + CONFIG = 2; + + // The snippet is handwritten. + HANDWRITTEN = 3; + } + + // A segment of the snippet. + message Segment { + // The line where this segment begins, inclusive. + // For the FULL segment, this will be the START region tag line + 1. + int32 start = 1; + + // The line where this segment ends, inclusive. + // For the FULL segment, this will be the END region tag line - 1. + int32 end = 2; + + // The type of the segment. + SegmentType type = 3; + + // The type of the segment. + // Basically describes what this segment shows. + enum SegmentType { + // The segment type has not been specified. Consumers should not see this + // value. + SEGMENT_TYPE_UNSPECIFIED = 0; + + // The full sample including import statements. + // This corresponds to the sample as determined by the region tags. + FULL = 1; + + // A shorter version of the full sample, may not include imports and some + // langauge specific initialization code. This is to be used in contexts + // in which the full aspects of the sample are made clear outside the + // code. + SHORT = 2; + + // The segment contains the service client initialization code only. + // To be used in tutorials, codelabs, etc. + CLIENT_INITIALIZATION = 3; + + // The segment contains the request initialization code only. + // To be used in tutorials, codelabs, etc. + REQUEST_INITIALIZATION = 4; + + // The segment contains the request execution code only. + // To be used in tutorials, codelabs, etc. + REQUEST_EXECUTION = 5; + + // The segment contains the response handling code only. + // To be used in tutorials, codelabs, etc. + RESPONSE_HANDLING = 6; + } + } +} + +// A client library method. +// Will contain language specific information. +message ClientMethod { + // The short name of the method, usually the name it is declared with. + // This may not be unique within the service client because of overloads. + string short_name = 1; + + // The fully qualified name of the method, which is the short_name qualified + // by the full_name of the service client. + // This value is redundant, but present to make it easier for consumers to + // obtain it. + // This may not be unique within the service client because of overloads. + string full_name = 2; + + // Indicates wether this method is synchronous or asynchronous. + // Some languages may support only one of the variants, in which case, this + // field will always have the same value (for that language). + bool async = 3; + + // Parameters of this method in the same order as they appear on the method + // declaration. Must be empty if the method has no parameters. + repeated Parameter parameters = 4; + + // Fully qualified type name of this method result, if any. + string result_type = 5; + + // The service client this method is declared in. + ServiceClient client = 6; + + // The service method this client method is for. + Method method = 7; + + // A method parameter as described by its type and name. + message Parameter { + // Fully qualified type name of this parameter. + // May be empty for languages that don't specify a type. + string type = 1; + + // Name of the parameter as it appears on the method declaration. + string name = 2; + } +} + +// A service client defined in the client library specified in Index. +// Will contain language specific information. +message ServiceClient { + // The short name of the service client, usually the name it is declared with. + // This may not be unique within the client library because of + // namespaces/packages. + string short_name = 1; + + // The fully qualified name of the service client, which is the short_name + // qualified by the namespace/package/type name this client is declared in. + // This will be unique within the client libray. + string full_name = 2; +} + +// A client library. +// Will contain language specific information. +message ClientLibrary { + // The name of the client library. This value will be language dependent + // and may or may not include the library version. + // Usually this will be the name used to identify the library on per-language + // package managers. + // Examples: "Google.Cloud.Translate.V3", + // "cloud.google.com/go/translate/apiv3". + string name = 1; + + // The full version of the client library. May also be language dependent. + // Cannot be updated on metadata generation, but on library release. + // Examples: "4.3.0", "2.5.2-beta01" + string version = 2; + + // The programming language the library is written in. + // Note that this does not contain information about the library supported + // platforms or language versions, etc. This is just a quick way to identify + // the generally supported langauge. + Language language = 3; + + // The APIs this client library is for. + // Some languages bundle several APIs on the same client library. + repeated Api apis = 4; +} + +message Method { + // The short name of the method, which is the name used to + // declare it within the proto file. This is unique within the service, + // but may not be unique within the API. + string short_name = 1; + + // The full name of the method, which is the short name qualified + // by the full name of the service in which it is declared. + // This is globally unique. + string full_name = 2; + + // The service this method is declared in. + Service service = 3; +} + +// A service defined in the API the client library referenced in Index is for. +message Service { + // The short name of the service, which is the name used to + // declare it within the proto file. This is usually, but not + // absolutely necessarily, unique within an API. + // Example: "TranslationService" + string short_name = 1; + + // The full name of the service, which is the short name qualified + // by the package of the proto in which it is declared. + // This is globally unique. + // Example: "google.cloud.translate.v3.TranslationService" + string full_name = 2; +} + +// An API +message Api { + // The ID of the API, identical to the protobuf package + // ending with a version number. + // Example: "google.cloud.translate.v3" + string id = 1; + + // The full version inferred from the end of the ID. + // Examples: "v3", "v2beta1", "v1beta" + string version = 2; +} + +// A programming language +enum Language { + // The language has not been specified. Consumers should not see this value. + LANGUAGE_UNSPECIFIED = 0; + + C_PLUS_PLUS = 1; + + C_SHARP = 2; + + DART = 3; + + ELIXIR = 4; + + ERLANG = 5; + + F_SHARP = 6; + + GO = 7; + + JAVA = 8; + + JAVASCRIPT = 9; + + KOTLIN = 10; + + PHP = 11; + + PYTHON = 12; + + RUBY = 13; + + RUST = 14; + + SWIFT = 15; + + TYPESCRIPT = 16; + + VB_NET = 17; +} \ No newline at end of file diff --git a/gapic/samplegen_utils/snippet_metadata_pb2.py b/gapic/samplegen_utils/snippet_metadata_pb2.py new file mode 100644 index 0000000000..73a75da6c2 --- /dev/null +++ b/gapic/samplegen_utils/snippet_metadata_pb2.py @@ -0,0 +1,840 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: snippet_metadata.proto + +# type: ignore + +"""Generated protocol buffer code.""" +from google.protobuf.internal import enum_type_wrapper +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='snippet_metadata.proto', + package='google.cloud.tools.snippetgen.snippetindex.v1', + syntax='proto3', + serialized_options=b'\252\002-Google.Cloud.Tools.SnippetGen.SnippetIndex.V1\312\002-Google\\Cloud\\Tools\\SnippetGen\\SnippetIndex\\V1\352\0022Google::Cloud::Tools::SnippetGen::SnippetIndex::V1', + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n\x16snippet_metadata.proto\x12-google.cloud.tools.snippetgen.snippetindex.v1\"\xa7\x01\n\x05Index\x12T\n\x0e\x63lient_library\x18\x01 \x01(\x0b\x32<.google.cloud.tools.snippetgen.snippetindex.v1.ClientLibrary\x12H\n\x08snippets\x18\x02 \x03(\x0b\x32\x36.google.cloud.tools.snippetgen.snippetindex.v1.Snippet\"\x9f\x06\n\x07Snippet\x12\x12\n\nregion_tag\x18\x01 \x01(\t\x12\r\n\x05title\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\x0c\n\x04\x66ile\x18\x04 \x01(\t\x12I\n\x08language\x18\x05 \x01(\x0e\x32\x37.google.cloud.tools.snippetgen.snippetindex.v1.Language\x12R\n\rclient_method\x18\x06 \x01(\x0b\x32;.google.cloud.tools.snippetgen.snippetindex.v1.ClientMethod\x12\x11\n\tcanonical\x18\x07 \x01(\x08\x12M\n\x06origin\x18\x08 \x01(\x0e\x32=.google.cloud.tools.snippetgen.snippetindex.v1.Snippet.Origin\x12P\n\x08segments\x18\t \x03(\x0b\x32>.google.cloud.tools.snippetgen.snippetindex.v1.Snippet.Segment\x1a\xa7\x02\n\x07Segment\x12\r\n\x05start\x18\x01 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x05\x12X\n\x04type\x18\x03 \x01(\x0e\x32J.google.cloud.tools.snippetgen.snippetindex.v1.Snippet.Segment.SegmentType\"\xa5\x01\n\x0bSegmentType\x12\x1c\n\x18SEGMENT_TYPE_UNSPECIFIED\x10\x00\x12\x08\n\x04\x46ULL\x10\x01\x12\t\n\x05SHORT\x10\x02\x12\x19\n\x15\x43LIENT_INITIALIZATION\x10\x03\x12\x1a\n\x16REQUEST_INITIALIZATION\x10\x04\x12\x15\n\x11REQUEST_EXECUTION\x10\x05\x12\x15\n\x11RESPONSE_HANDLING\x10\x06\"Q\n\x06Origin\x12\x16\n\x12ORIGIN_UNSPECIFIED\x10\x00\x12\x12\n\x0e\x41PI_DEFINITION\x10\x01\x12\n\n\x06\x43ONFIG\x10\x02\x12\x0f\n\x0bHANDWRITTEN\x10\x03\"\xf2\x02\n\x0c\x43lientMethod\x12\x12\n\nshort_name\x18\x01 \x01(\t\x12\x11\n\tfull_name\x18\x02 \x01(\t\x12\r\n\x05\x61sync\x18\x03 \x01(\x08\x12Y\n\nparameters\x18\x04 \x03(\x0b\x32\x45.google.cloud.tools.snippetgen.snippetindex.v1.ClientMethod.Parameter\x12\x13\n\x0bresult_type\x18\x05 \x01(\t\x12L\n\x06\x63lient\x18\x06 \x01(\x0b\x32<.google.cloud.tools.snippetgen.snippetindex.v1.ServiceClient\x12\x45\n\x06method\x18\x07 \x01(\x0b\x32\x35.google.cloud.tools.snippetgen.snippetindex.v1.Method\x1a\'\n\tParameter\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"6\n\rServiceClient\x12\x12\n\nshort_name\x18\x01 \x01(\t\x12\x11\n\tfull_name\x18\x02 \x01(\t\"\xbb\x01\n\rClientLibrary\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\t\x12I\n\x08language\x18\x03 \x01(\x0e\x32\x37.google.cloud.tools.snippetgen.snippetindex.v1.Language\x12@\n\x04\x61pis\x18\x04 \x03(\x0b\x32\x32.google.cloud.tools.snippetgen.snippetindex.v1.Api\"x\n\x06Method\x12\x12\n\nshort_name\x18\x01 \x01(\t\x12\x11\n\tfull_name\x18\x02 \x01(\t\x12G\n\x07service\x18\x03 \x01(\x0b\x32\x36.google.cloud.tools.snippetgen.snippetindex.v1.Service\"0\n\x07Service\x12\x12\n\nshort_name\x18\x01 \x01(\t\x12\x11\n\tfull_name\x18\x02 \x01(\t\"\"\n\x03\x41pi\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\t*\xef\x01\n\x08Language\x12\x18\n\x14LANGUAGE_UNSPECIFIED\x10\x00\x12\x0f\n\x0b\x43_PLUS_PLUS\x10\x01\x12\x0b\n\x07\x43_SHARP\x10\x02\x12\x08\n\x04\x44\x41RT\x10\x03\x12\n\n\x06\x45LIXIR\x10\x04\x12\n\n\x06\x45RLANG\x10\x05\x12\x0b\n\x07\x46_SHARP\x10\x06\x12\x06\n\x02GO\x10\x07\x12\x08\n\x04JAVA\x10\x08\x12\x0e\n\nJAVASCRIPT\x10\t\x12\n\n\x06KOTLIN\x10\n\x12\x07\n\x03PHP\x10\x0b\x12\n\n\x06PYTHON\x10\x0c\x12\x08\n\x04RUBY\x10\r\x12\x08\n\x04RUST\x10\x0e\x12\t\n\x05SWIFT\x10\x0f\x12\x0e\n\nTYPESCRIPT\x10\x10\x12\n\n\x06VB_NET\x10\x11\x42\x95\x01\xaa\x02-Google.Cloud.Tools.SnippetGen.SnippetIndex.V1\xca\x02-Google\\Cloud\\Tools\\SnippetGen\\SnippetIndex\\V1\xea\x02\x32Google::Cloud::Tools::SnippetGen::SnippetIndex::V1b\x06proto3' +) + +_LANGUAGE = _descriptor.EnumDescriptor( + name='Language', + full_name='google.cloud.tools.snippetgen.snippetindex.v1.Language', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='LANGUAGE_UNSPECIFIED', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='C_PLUS_PLUS', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='C_SHARP', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='DART', index=3, number=3, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='ELIXIR', index=4, number=4, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='ERLANG', index=5, number=5, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='F_SHARP', index=6, number=6, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='GO', index=7, number=7, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='JAVA', index=8, number=8, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='JAVASCRIPT', index=9, number=9, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='KOTLIN', index=10, number=10, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='PHP', index=11, number=11, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='PYTHON', index=12, number=12, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='RUBY', index=13, number=13, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='RUST', index=14, number=14, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='SWIFT', index=15, number=15, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TYPESCRIPT', index=16, number=16, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='VB_NET', index=17, number=17, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + serialized_start=1873, + serialized_end=2112, +) +_sym_db.RegisterEnumDescriptor(_LANGUAGE) + +Language = enum_type_wrapper.EnumTypeWrapper(_LANGUAGE) +LANGUAGE_UNSPECIFIED = 0 +C_PLUS_PLUS = 1 +C_SHARP = 2 +DART = 3 +ELIXIR = 4 +ERLANG = 5 +F_SHARP = 6 +GO = 7 +JAVA = 8 +JAVASCRIPT = 9 +KOTLIN = 10 +PHP = 11 +PYTHON = 12 +RUBY = 13 +RUST = 14 +SWIFT = 15 +TYPESCRIPT = 16 +VB_NET = 17 + + +_SNIPPET_SEGMENT_SEGMENTTYPE = _descriptor.EnumDescriptor( + name='SegmentType', + full_name='google.cloud.tools.snippetgen.snippetindex.v1.Snippet.Segment.SegmentType', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='SEGMENT_TYPE_UNSPECIFIED', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='FULL', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='SHORT', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='CLIENT_INITIALIZATION', index=3, number=3, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='REQUEST_INITIALIZATION', index=4, number=4, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='REQUEST_EXECUTION', index=5, number=5, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='RESPONSE_HANDLING', index=6, number=6, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + serialized_start=795, + serialized_end=960, +) +_sym_db.RegisterEnumDescriptor(_SNIPPET_SEGMENT_SEGMENTTYPE) + +_SNIPPET_ORIGIN = _descriptor.EnumDescriptor( + name='Origin', + full_name='google.cloud.tools.snippetgen.snippetindex.v1.Snippet.Origin', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='ORIGIN_UNSPECIFIED', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='API_DEFINITION', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='CONFIG', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='HANDWRITTEN', index=3, number=3, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + serialized_start=962, + serialized_end=1043, +) +_sym_db.RegisterEnumDescriptor(_SNIPPET_ORIGIN) + + +_INDEX = _descriptor.Descriptor( + name='Index', + full_name='google.cloud.tools.snippetgen.snippetindex.v1.Index', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='client_library', full_name='google.cloud.tools.snippetgen.snippetindex.v1.Index.client_library', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='snippets', full_name='google.cloud.tools.snippetgen.snippetindex.v1.Index.snippets', index=1, + number=2, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=74, + serialized_end=241, +) + + +_SNIPPET_SEGMENT = _descriptor.Descriptor( + name='Segment', + full_name='google.cloud.tools.snippetgen.snippetindex.v1.Snippet.Segment', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='start', full_name='google.cloud.tools.snippetgen.snippetindex.v1.Snippet.Segment.start', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='end', full_name='google.cloud.tools.snippetgen.snippetindex.v1.Snippet.Segment.end', index=1, + number=2, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='type', full_name='google.cloud.tools.snippetgen.snippetindex.v1.Snippet.Segment.type', index=2, + number=3, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + _SNIPPET_SEGMENT_SEGMENTTYPE, + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=665, + serialized_end=960, +) + +_SNIPPET = _descriptor.Descriptor( + name='Snippet', + full_name='google.cloud.tools.snippetgen.snippetindex.v1.Snippet', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='region_tag', full_name='google.cloud.tools.snippetgen.snippetindex.v1.Snippet.region_tag', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='title', full_name='google.cloud.tools.snippetgen.snippetindex.v1.Snippet.title', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='description', full_name='google.cloud.tools.snippetgen.snippetindex.v1.Snippet.description', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='file', full_name='google.cloud.tools.snippetgen.snippetindex.v1.Snippet.file', index=3, + number=4, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='language', full_name='google.cloud.tools.snippetgen.snippetindex.v1.Snippet.language', index=4, + number=5, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='client_method', full_name='google.cloud.tools.snippetgen.snippetindex.v1.Snippet.client_method', index=5, + number=6, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='canonical', full_name='google.cloud.tools.snippetgen.snippetindex.v1.Snippet.canonical', index=6, + number=7, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='origin', full_name='google.cloud.tools.snippetgen.snippetindex.v1.Snippet.origin', index=7, + number=8, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='segments', full_name='google.cloud.tools.snippetgen.snippetindex.v1.Snippet.segments', index=8, + number=9, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[_SNIPPET_SEGMENT, ], + enum_types=[ + _SNIPPET_ORIGIN, + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=244, + serialized_end=1043, +) + + +_CLIENTMETHOD_PARAMETER = _descriptor.Descriptor( + name='Parameter', + full_name='google.cloud.tools.snippetgen.snippetindex.v1.ClientMethod.Parameter', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='type', full_name='google.cloud.tools.snippetgen.snippetindex.v1.ClientMethod.Parameter.type', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='name', full_name='google.cloud.tools.snippetgen.snippetindex.v1.ClientMethod.Parameter.name', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1377, + serialized_end=1416, +) + +_CLIENTMETHOD = _descriptor.Descriptor( + name='ClientMethod', + full_name='google.cloud.tools.snippetgen.snippetindex.v1.ClientMethod', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='short_name', full_name='google.cloud.tools.snippetgen.snippetindex.v1.ClientMethod.short_name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='full_name', full_name='google.cloud.tools.snippetgen.snippetindex.v1.ClientMethod.full_name', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='async', full_name='google.cloud.tools.snippetgen.snippetindex.v1.ClientMethod.async', index=2, + number=3, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='parameters', full_name='google.cloud.tools.snippetgen.snippetindex.v1.ClientMethod.parameters', index=3, + number=4, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='result_type', full_name='google.cloud.tools.snippetgen.snippetindex.v1.ClientMethod.result_type', index=4, + number=5, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='client', full_name='google.cloud.tools.snippetgen.snippetindex.v1.ClientMethod.client', index=5, + number=6, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='method', full_name='google.cloud.tools.snippetgen.snippetindex.v1.ClientMethod.method', index=6, + number=7, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[_CLIENTMETHOD_PARAMETER, ], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1046, + serialized_end=1416, +) + + +_SERVICECLIENT = _descriptor.Descriptor( + name='ServiceClient', + full_name='google.cloud.tools.snippetgen.snippetindex.v1.ServiceClient', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='short_name', full_name='google.cloud.tools.snippetgen.snippetindex.v1.ServiceClient.short_name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='full_name', full_name='google.cloud.tools.snippetgen.snippetindex.v1.ServiceClient.full_name', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1418, + serialized_end=1472, +) + + +_CLIENTLIBRARY = _descriptor.Descriptor( + name='ClientLibrary', + full_name='google.cloud.tools.snippetgen.snippetindex.v1.ClientLibrary', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='google.cloud.tools.snippetgen.snippetindex.v1.ClientLibrary.name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='version', full_name='google.cloud.tools.snippetgen.snippetindex.v1.ClientLibrary.version', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='language', full_name='google.cloud.tools.snippetgen.snippetindex.v1.ClientLibrary.language', index=2, + number=3, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='apis', full_name='google.cloud.tools.snippetgen.snippetindex.v1.ClientLibrary.apis', index=3, + number=4, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1475, + serialized_end=1662, +) + + +_METHOD = _descriptor.Descriptor( + name='Method', + full_name='google.cloud.tools.snippetgen.snippetindex.v1.Method', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='short_name', full_name='google.cloud.tools.snippetgen.snippetindex.v1.Method.short_name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='full_name', full_name='google.cloud.tools.snippetgen.snippetindex.v1.Method.full_name', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='service', full_name='google.cloud.tools.snippetgen.snippetindex.v1.Method.service', index=2, + number=3, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1664, + serialized_end=1784, +) + + +_SERVICE = _descriptor.Descriptor( + name='Service', + full_name='google.cloud.tools.snippetgen.snippetindex.v1.Service', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='short_name', full_name='google.cloud.tools.snippetgen.snippetindex.v1.Service.short_name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='full_name', full_name='google.cloud.tools.snippetgen.snippetindex.v1.Service.full_name', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1786, + serialized_end=1834, +) + + +_API = _descriptor.Descriptor( + name='Api', + full_name='google.cloud.tools.snippetgen.snippetindex.v1.Api', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='id', full_name='google.cloud.tools.snippetgen.snippetindex.v1.Api.id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='version', full_name='google.cloud.tools.snippetgen.snippetindex.v1.Api.version', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1836, + serialized_end=1870, +) + +_INDEX.fields_by_name['client_library'].message_type = _CLIENTLIBRARY +_INDEX.fields_by_name['snippets'].message_type = _SNIPPET +_SNIPPET_SEGMENT.fields_by_name['type'].enum_type = _SNIPPET_SEGMENT_SEGMENTTYPE +_SNIPPET_SEGMENT.containing_type = _SNIPPET +_SNIPPET_SEGMENT_SEGMENTTYPE.containing_type = _SNIPPET_SEGMENT +_SNIPPET.fields_by_name['language'].enum_type = _LANGUAGE +_SNIPPET.fields_by_name['client_method'].message_type = _CLIENTMETHOD +_SNIPPET.fields_by_name['origin'].enum_type = _SNIPPET_ORIGIN +_SNIPPET.fields_by_name['segments'].message_type = _SNIPPET_SEGMENT +_SNIPPET_ORIGIN.containing_type = _SNIPPET +_CLIENTMETHOD_PARAMETER.containing_type = _CLIENTMETHOD +_CLIENTMETHOD.fields_by_name['parameters'].message_type = _CLIENTMETHOD_PARAMETER +_CLIENTMETHOD.fields_by_name['client'].message_type = _SERVICECLIENT +_CLIENTMETHOD.fields_by_name['method'].message_type = _METHOD +_CLIENTLIBRARY.fields_by_name['language'].enum_type = _LANGUAGE +_CLIENTLIBRARY.fields_by_name['apis'].message_type = _API +_METHOD.fields_by_name['service'].message_type = _SERVICE +DESCRIPTOR.message_types_by_name['Index'] = _INDEX +DESCRIPTOR.message_types_by_name['Snippet'] = _SNIPPET +DESCRIPTOR.message_types_by_name['ClientMethod'] = _CLIENTMETHOD +DESCRIPTOR.message_types_by_name['ServiceClient'] = _SERVICECLIENT +DESCRIPTOR.message_types_by_name['ClientLibrary'] = _CLIENTLIBRARY +DESCRIPTOR.message_types_by_name['Method'] = _METHOD +DESCRIPTOR.message_types_by_name['Service'] = _SERVICE +DESCRIPTOR.message_types_by_name['Api'] = _API +DESCRIPTOR.enum_types_by_name['Language'] = _LANGUAGE +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +Index = _reflection.GeneratedProtocolMessageType('Index', (_message.Message,), { + 'DESCRIPTOR': _INDEX, + '__module__': 'snippet_metadata_pb2' + # @@protoc_insertion_point(class_scope:google.cloud.tools.snippetgen.snippetindex.v1.Index) + }) +_sym_db.RegisterMessage(Index) + +Snippet = _reflection.GeneratedProtocolMessageType('Snippet', (_message.Message,), { + + 'Segment': _reflection.GeneratedProtocolMessageType('Segment', (_message.Message,), { + 'DESCRIPTOR': _SNIPPET_SEGMENT, + '__module__': 'snippet_metadata_pb2' + # @@protoc_insertion_point(class_scope:google.cloud.tools.snippetgen.snippetindex.v1.Snippet.Segment) + }), + 'DESCRIPTOR': _SNIPPET, + '__module__': 'snippet_metadata_pb2' + # @@protoc_insertion_point(class_scope:google.cloud.tools.snippetgen.snippetindex.v1.Snippet) + }) +_sym_db.RegisterMessage(Snippet) +_sym_db.RegisterMessage(Snippet.Segment) + +ClientMethod = _reflection.GeneratedProtocolMessageType('ClientMethod', (_message.Message,), { + + 'Parameter': _reflection.GeneratedProtocolMessageType('Parameter', (_message.Message,), { + 'DESCRIPTOR': _CLIENTMETHOD_PARAMETER, + '__module__': 'snippet_metadata_pb2' + # @@protoc_insertion_point(class_scope:google.cloud.tools.snippetgen.snippetindex.v1.ClientMethod.Parameter) + }), + 'DESCRIPTOR': _CLIENTMETHOD, + '__module__': 'snippet_metadata_pb2' + # @@protoc_insertion_point(class_scope:google.cloud.tools.snippetgen.snippetindex.v1.ClientMethod) + }) +_sym_db.RegisterMessage(ClientMethod) +_sym_db.RegisterMessage(ClientMethod.Parameter) + +ServiceClient = _reflection.GeneratedProtocolMessageType('ServiceClient', (_message.Message,), { + 'DESCRIPTOR': _SERVICECLIENT, + '__module__': 'snippet_metadata_pb2' + # @@protoc_insertion_point(class_scope:google.cloud.tools.snippetgen.snippetindex.v1.ServiceClient) + }) +_sym_db.RegisterMessage(ServiceClient) + +ClientLibrary = _reflection.GeneratedProtocolMessageType('ClientLibrary', (_message.Message,), { + 'DESCRIPTOR': _CLIENTLIBRARY, + '__module__': 'snippet_metadata_pb2' + # @@protoc_insertion_point(class_scope:google.cloud.tools.snippetgen.snippetindex.v1.ClientLibrary) + }) +_sym_db.RegisterMessage(ClientLibrary) + +Method = _reflection.GeneratedProtocolMessageType('Method', (_message.Message,), { + 'DESCRIPTOR': _METHOD, + '__module__': 'snippet_metadata_pb2' + # @@protoc_insertion_point(class_scope:google.cloud.tools.snippetgen.snippetindex.v1.Method) + }) +_sym_db.RegisterMessage(Method) + +Service = _reflection.GeneratedProtocolMessageType('Service', (_message.Message,), { + 'DESCRIPTOR': _SERVICE, + '__module__': 'snippet_metadata_pb2' + # @@protoc_insertion_point(class_scope:google.cloud.tools.snippetgen.snippetindex.v1.Service) + }) +_sym_db.RegisterMessage(Service) + +Api = _reflection.GeneratedProtocolMessageType('Api', (_message.Message,), { + 'DESCRIPTOR': _API, + '__module__': 'snippet_metadata_pb2' + # @@protoc_insertion_point(class_scope:google.cloud.tools.snippetgen.snippetindex.v1.Api) + }) +_sym_db.RegisterMessage(Api) + + +DESCRIPTOR._options = None +# @@protoc_insertion_point(module_scope) diff --git a/tests/unit/samplegen/common_types.py b/tests/unit/samplegen/common_types.py index 538b9d6864..1d10553b7d 100644 --- a/tests/unit/samplegen/common_types.py +++ b/tests/unit/samplegen/common_types.py @@ -91,7 +91,7 @@ def resource_path_args(self): DummyService = namedtuple("DummyService", [ - "methods", "client_name", "async_client_name", "resource_messages_dict"]) + "name", "methods", "client_name", "async_client_name", "resource_messages_dict"]) DummyService.__new__.__defaults__ = (False,) * len(DummyService._fields) DummyApiSchema = namedtuple("DummyApiSchema", diff --git a/tests/unit/samplegen/test_snippet_index.py b/tests/unit/samplegen/test_snippet_index.py new file mode 100644 index 0000000000..09f782a099 --- /dev/null +++ b/tests/unit/samplegen/test_snippet_index.py @@ -0,0 +1,229 @@ +# Copyright 2022 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. + +import json + +from google.protobuf import json_format +import pytest + +from gapic.samplegen_utils import snippet_metadata_pb2 +from gapic.samplegen_utils import snippet_index, types +from common_types import DummyApiSchema, DummyService, DummyMethod + + +@pytest.fixture +def sample_str(): + return """# [START mollusc_classify_sync] +from molluscs.v1 import molluscclient + + +def sample_classify(video, location): + # Create a client + client = molluscclient.MolluscServiceClient() + + # Initialize request argument(s) + classify_target = molluscclient.ClassifyTarget() + + # video = "path/to/mollusc/video.mkv" + with open(video, "rb") as f: + classify_target.video = f.read() + + # location = "New Zealand" + classify_target.location_annotation = location + + request = molluscclient.molluscs.v1.ClassifyRequest( + classify_target=classify_target, + ) + + # Make the request + response = client.classify(request=request) + + # Handle response + print(f"Mollusc is a \"{response.taxonomy}\"") + +# [END mollusc_classify_sync]""" + + +def test_snippet_init(sample_str): + # We are not trying to exhaustively test the snippet metadata protobuf, + # just checking that fields are not unset + sample_metadata = snippet_metadata_pb2.Snippet(title="classify_squid.py") + sample_metadata.language = snippet_metadata_pb2.Language.PYTHON + snippet = snippet_index.Snippet(sample_str, sample_metadata) + + assert snippet.sample_str == sample_str + + # It's easier to eyeball diffs on the dictionary representation + assert json_format.MessageToDict(snippet.metadata) == { + "language": "PYTHON", + "title": "classify_squid.py", + "segments": [ + {"end": 28, "start": 2, "type": "FULL"}, + {"end": 28, "start": 2, "type": "SHORT"}, + {"end": 8, "start": 6, "type": "CLIENT_INITIALIZATION"}, + {"end": 22, "start": 9, "type": "REQUEST_INITIALIZATION"}, + {"end": 25, "start": 23, "type": "REQUEST_EXECUTION"}, + {"end": 29, "start": 26, "type": "RESPONSE_HANDLING"}, + ] + } + + # This is the same as the sample_str above, minus the # [START ...] + # and # [END ...] lines + expected_full_snipppet = """from molluscs.v1 import molluscclient + + +def sample_classify(video, location): + # Create a client + client = molluscclient.MolluscServiceClient() + + # Initialize request argument(s) + classify_target = molluscclient.ClassifyTarget() + + # video = "path/to/mollusc/video.mkv" + with open(video, "rb") as f: + classify_target.video = f.read() + + # location = "New Zealand" + classify_target.location_annotation = location + + request = molluscclient.molluscs.v1.ClassifyRequest( + classify_target=classify_target, + ) + + # Make the request + response = client.classify(request=request) + + # Handle response + print(f"Mollusc is a \"{response.taxonomy}\"") + +""" + + assert snippet.full_snippet == expected_full_snipppet + + +def test_add_snippet_no_matching_service(sample_str): + snippet_metadata = snippet_metadata_pb2.Snippet( + ) + snippet_metadata.client_method.method.service.short_name = "Clam" + snippet = snippet_index.Snippet(sample_str, snippet_metadata) + + # No 'Clam' service in API Schema + index = snippet_index.SnippetIndex(api_schema=DummyApiSchema( + services={"Squid": DummyService(name="Squid", methods={})} + )) + with pytest.raises(types.UnknownService): + index.add_snippet(snippet) + + +def test_add_snippet_no_matching_rpc(sample_str): + snippet_metadata = snippet_metadata_pb2.Snippet( + ) + snippet_metadata.client_method.method.service.short_name = "Squid" + snippet_metadata.client_method.full_name = "classify" + snippet = snippet_index.Snippet(sample_str, snippet_metadata) + + # No 'classify' method in 'Squid' service + index = snippet_index.SnippetIndex(api_schema=DummyApiSchema( + services={"Squid": DummyService(name="Squid", methods={"list": None})} + )) + with pytest.raises(types.RpcMethodNotFound): + index.add_snippet(snippet) + + +def test_get_snippet_no_matching_service(): + index = snippet_index.SnippetIndex(api_schema=DummyApiSchema( + services={"Squid": DummyService( + name="Squid", methods={"classify": DummyMethod()})} + )) + + # No 'Clam' service in API Schema + with pytest.raises(types.UnknownService): + index.get_snippet(service_name="Clam", rpc_name="classify") + + +def test_get_snippet_no_matching_rpc(): + index = snippet_index.SnippetIndex(api_schema=DummyApiSchema( + services={"Squid": DummyService( + name="Squid", methods={"classify": DummyMethod()})} + )) + + # No 'list' RPC in 'Squid' service + with pytest.raises(types.RpcMethodNotFound): + index.get_snippet(service_name="Squid", rpc_name="list") + + +def test_add_and_get_snippet_sync(sample_str): + snippet_metadata = snippet_metadata_pb2.Snippet() + snippet_metadata.client_method.method.service.short_name = "Squid" + snippet_metadata.client_method.method.full_name = "classify" + snippet = snippet_index.Snippet(sample_str, snippet_metadata) + + index = snippet_index.SnippetIndex(api_schema=DummyApiSchema( + services={"Squid": DummyService( + name="Squid", methods={"classify": DummyMethod()})} + )) + + index.add_snippet(snippet) + + index.get_snippet(service_name="Squid", rpc_name="classify") + + +def test_add_and_get_snippet_async(sample_str): + snippet_metadata = snippet_metadata_pb2.Snippet() + snippet_metadata.client_method.method.service.short_name = "Squid" + snippet_metadata.client_method.method.full_name = "classify" + setattr(snippet_metadata.client_method, "async", True) + snippet = snippet_index.Snippet(sample_str, snippet_metadata) + + index = snippet_index.SnippetIndex(api_schema=DummyApiSchema( + services={"Squid": DummyService( + name="Squid", methods={"classify": DummyMethod()})} + )) + + index.add_snippet(snippet) + + index.get_snippet(service_name="Squid", rpc_name="classify", sync=False) + + +def test_get_metadata_json(sample_str): + snippet_metadata = snippet_metadata_pb2.Snippet() + snippet_metadata.client_method.method.service.short_name = "Squid" + snippet_metadata.client_method.method.full_name = "classify" + snippet = snippet_index.Snippet(sample_str, snippet_metadata) + + index = snippet_index.SnippetIndex(api_schema=DummyApiSchema( + services={"Squid": DummyService( + name="Squid", methods={"classify": DummyMethod()})} + )) + + index.add_snippet(snippet) + + assert json.loads(index.get_metadata_json()) == { + 'snippets': [{'clientMethod': {'method': {'fullName': 'classify', + 'service': {'shortName': 'Squid'}}}, + 'segments': [{'end': 28, 'start': 2, 'type': 'FULL'}, + {'end': 28, 'start': 2, 'type': 'SHORT'}, + {'end': 8, + 'start': 6, + 'type': 'CLIENT_INITIALIZATION'}, + {'end': 22, + 'start': 9, + 'type': 'REQUEST_INITIALIZATION'}, + {'end': 25, + 'start': 23, + 'type': 'REQUEST_EXECUTION'}, + {'end': 29, + 'start': 26, + 'type': 'RESPONSE_HANDLING'}]}] + }