diff --git a/gapic/samplegen/samplegen.py b/gapic/samplegen/samplegen.py index ab1b817300..35667f5af6 100644 --- a/gapic/samplegen/samplegen.py +++ b/gapic/samplegen/samplegen.py @@ -30,7 +30,7 @@ from gapic.schema import wrappers from collections import defaultdict, namedtuple, ChainMap as chainmap -from typing import Any, ChainMap, Dict, FrozenSet, Generator, List, Mapping, Optional, Tuple, Sequence +from typing import Any, ChainMap, Dict, FrozenSet, Generator, List, Mapping, Optional, Sequence # There is no library stub file for this module, so ignore it. from google.api import resource_pb2 # type: ignore @@ -981,10 +981,16 @@ def generate_request_object(api_schema: api.API, service: wrappers.Service, mess request_fields: List[wrappers.Field] = [] - # Choose the first option for each oneof + # There is no standard syntax to mark a oneof as "required" in protos. + # Assume every oneof is required and pick the first option + # in each oneof. selected_oneofs: List[wrappers.Field] = [oneof_fields[0] for oneof_fields in message.oneof_fields().values()] - request_fields = selected_oneofs + message.required_fields + + # Don't add required fields if they're also marked as oneof + required_fields = [ + field for field in message.required_fields if not field.oneof] + request_fields = selected_oneofs + required_fields for field in request_fields: # TransformedRequest expects nested fields to be referenced like diff --git a/tests/snippetgen/goldens/mollusca_generated_mollusca_v1_snippets_one_of_method_required_field_async.py b/tests/snippetgen/goldens/mollusca_generated_mollusca_v1_snippets_one_of_method_required_field_async.py new file mode 100644 index 0000000000..4f074994b7 --- /dev/null +++ b/tests/snippetgen/goldens/mollusca_generated_mollusca_v1_snippets_one_of_method_required_field_async.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for OneOfMethodRequiredField +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install animalia-mollusca + + +# [START mollusca_generated_mollusca_v1_Snippets_OneOfMethodRequiredField_async] +from animalia import mollusca_v1 + + +async def sample_one_of_method_required_field(): + """Snippet for one_of_method_required_field""" + + # Create a client + client = mollusca_v1.SnippetsAsyncClient() + + # Initialize request argument(s) + request = mollusca_v1.OneOfRequestWithRequiredField( + my_string="my_string_value", + non_one_of_string="non_one_of_string_value", + ) + + # Make the request + response = await client.one_of_method_required_field(request=request) + + # Handle response + print(response) + +# [END mollusca_generated_mollusca_v1_Snippets_OneOfMethodRequiredField_async] diff --git a/tests/snippetgen/goldens/mollusca_generated_mollusca_v1_snippets_one_of_method_required_field_sync.py b/tests/snippetgen/goldens/mollusca_generated_mollusca_v1_snippets_one_of_method_required_field_sync.py new file mode 100644 index 0000000000..6e480d5000 --- /dev/null +++ b/tests/snippetgen/goldens/mollusca_generated_mollusca_v1_snippets_one_of_method_required_field_sync.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for OneOfMethodRequiredField +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install animalia-mollusca + + +# [START mollusca_generated_mollusca_v1_Snippets_OneOfMethodRequiredField_sync] +from animalia import mollusca_v1 + + +def sample_one_of_method_required_field(): + """Snippet for one_of_method_required_field""" + + # Create a client + client = mollusca_v1.SnippetsClient() + + # Initialize request argument(s) + request = mollusca_v1.OneOfRequestWithRequiredField( + my_string="my_string_value", + non_one_of_string="non_one_of_string_value", + ) + + # Make the request + response = client.one_of_method_required_field(request=request) + + # Handle response + print(response) + +# [END mollusca_generated_mollusca_v1_Snippets_OneOfMethodRequiredField_sync] diff --git a/tests/snippetgen/snippets.proto b/tests/snippetgen/snippets.proto index fbffcea258..d5ead4ed33 100644 --- a/tests/snippetgen/snippets.proto +++ b/tests/snippetgen/snippets.proto @@ -55,6 +55,8 @@ service Snippets { rpc MethodBidiStreaming(stream SignatureRequestOneRequiredField) returns (stream Response); rpc OneOfMethod(OneOfRequest) returns (Response); + + rpc OneOfMethodRequiredField(OneOfRequestWithRequiredField) returns (Response); } enum Enum { @@ -149,3 +151,14 @@ message OneOfRequest { int32 my_number = 3; } } + + +message OneOfRequestWithRequiredField { + string non_one_of_string = 1 [(google.api.field_behavior) = REQUIRED]; + + // Some APIs mark every field in a "required" oneof as required + oneof my_one_of { + string my_string = 2 [(google.api.field_behavior) = REQUIRED]; + int32 my_number = 3 [(google.api.field_behavior) = REQUIRED]; + } +} \ No newline at end of file