|
64 | 64 | from gapic.utils import Options |
65 | 65 | from gapic.utils import to_snake_case |
66 | 66 | from gapic.utils import RESERVED_NAMES |
| 67 | +from gapic.utils.cache import generation_cache_context |
67 | 68 |
|
68 | 69 |
|
69 | 70 | TRANSPORT_GRPC = "grpc" |
@@ -454,115 +455,116 @@ def disambiguate_keyword_sanitize_fname( |
454 | 455 | # type into the proto file that defines an LRO. |
455 | 456 | # We just load all the APIs types first and then |
456 | 457 | # load the services and methods with the full scope of types. |
457 | | - pre_protos: Dict[str, Proto] = dict(prior_protos or {}) |
458 | | - for fd in file_descriptors: |
459 | | - fd.name = disambiguate_keyword_sanitize_fname(fd.name, pre_protos) |
460 | | - pre_protos[fd.name] = Proto.build( |
461 | | - file_descriptor=fd, |
462 | | - file_to_generate=fd.package.startswith(package), |
463 | | - naming=naming, |
464 | | - opts=opts, |
465 | | - prior_protos=pre_protos, |
466 | | - # Ugly, ugly hack. |
467 | | - load_services=False, |
| 458 | + with generation_cache_context(): |
| 459 | + pre_protos: Dict[str, Proto] = dict(prior_protos or {}) |
| 460 | + for fd in file_descriptors: |
| 461 | + fd.name = disambiguate_keyword_sanitize_fname(fd.name, pre_protos) |
| 462 | + pre_protos[fd.name] = Proto.build( |
| 463 | + file_descriptor=fd, |
| 464 | + file_to_generate=fd.package.startswith(package), |
| 465 | + naming=naming, |
| 466 | + opts=opts, |
| 467 | + prior_protos=pre_protos, |
| 468 | + # Ugly, ugly hack. |
| 469 | + load_services=False, |
| 470 | + ) |
| 471 | + |
| 472 | + # A file descriptor's file-level resources are NOT visible to any importers. |
| 473 | + # The only way to make referenced resources visible is to aggregate them at |
| 474 | + # the API level and then pass that around. |
| 475 | + all_file_resources = collections.ChainMap( |
| 476 | + *(proto.resource_messages for proto in pre_protos.values()) |
468 | 477 | ) |
469 | 478 |
|
470 | | - # A file descriptor's file-level resources are NOT visible to any importers. |
471 | | - # The only way to make referenced resources visible is to aggregate them at |
472 | | - # the API level and then pass that around. |
473 | | - all_file_resources = collections.ChainMap( |
474 | | - *(proto.resource_messages for proto in pre_protos.values()) |
475 | | - ) |
| 479 | + # Second pass uses all the messages and enums defined in the entire API. |
| 480 | + # This allows LRO returning methods to see all the types in the API, |
| 481 | + # bypassing the above missing import problem. |
| 482 | + protos: Dict[str, Proto] = { |
| 483 | + name: Proto.build( |
| 484 | + file_descriptor=proto.file_pb2, |
| 485 | + file_to_generate=proto.file_to_generate, |
| 486 | + naming=naming, |
| 487 | + opts=opts, |
| 488 | + prior_protos=pre_protos, |
| 489 | + all_resources=MappingProxyType(all_file_resources), |
| 490 | + ) |
| 491 | + for name, proto in pre_protos.items() |
| 492 | + } |
476 | 493 |
|
477 | | - # Second pass uses all the messages and enums defined in the entire API. |
478 | | - # This allows LRO returning methods to see all the types in the API, |
479 | | - # bypassing the above missing import problem. |
480 | | - protos: Dict[str, Proto] = { |
481 | | - name: Proto.build( |
482 | | - file_descriptor=proto.file_pb2, |
483 | | - file_to_generate=proto.file_to_generate, |
484 | | - naming=naming, |
485 | | - opts=opts, |
486 | | - prior_protos=pre_protos, |
487 | | - all_resources=MappingProxyType(all_file_resources), |
| 494 | + # Parse the google.api.Service proto from the service_yaml data. |
| 495 | + service_yaml_config = service_pb2.Service() |
| 496 | + ParseDict( |
| 497 | + opts.service_yaml_config, service_yaml_config, ignore_unknown_fields=True |
488 | 498 | ) |
489 | | - for name, proto in pre_protos.items() |
490 | | - } |
| 499 | + gapic_version = opts.gapic_version |
491 | 500 |
|
492 | | - # Parse the google.api.Service proto from the service_yaml data. |
493 | | - service_yaml_config = service_pb2.Service() |
494 | | - ParseDict( |
495 | | - opts.service_yaml_config, service_yaml_config, ignore_unknown_fields=True |
496 | | - ) |
497 | | - gapic_version = opts.gapic_version |
498 | | - |
499 | | - # Third pass for various selective GAPIC settings; these require |
500 | | - # settings in the service.yaml and so we build the API object |
501 | | - # before doing another pass. |
502 | | - api = cls( |
503 | | - naming=naming, |
504 | | - all_protos=protos, |
505 | | - service_yaml_config=service_yaml_config, |
506 | | - gapic_version=gapic_version, |
507 | | - ) |
| 501 | + # Third pass for various selective GAPIC settings; these require |
| 502 | + # settings in the service.yaml and so we build the API object |
| 503 | + # before doing another pass. |
| 504 | + api = cls( |
| 505 | + naming=naming, |
| 506 | + all_protos=protos, |
| 507 | + service_yaml_config=service_yaml_config, |
| 508 | + gapic_version=gapic_version, |
| 509 | + ) |
508 | 510 |
|
509 | | - if package in api.all_library_settings: |
510 | | - selective_gapic_settings = api.all_library_settings[ |
511 | | - package |
512 | | - ].python_settings.common.selective_gapic_generation |
513 | | - |
514 | | - selective_gapic_methods = set(selective_gapic_settings.methods) |
515 | | - if selective_gapic_methods: |
516 | | - # The list of explicitly allow-listed protos to generate, plus all |
517 | | - # the proto dependencies regardless of the allow-list. |
518 | | - # |
519 | | - # Both selective GAPIC generation settings (omitting + internal) only alter |
520 | | - # protos that are not dependencies, so we iterate over api.all_protos and copy |
521 | | - # all dependencies as is here. |
522 | | - new_all_protos = { |
523 | | - k: v for k, v in api.all_protos.items() if k not in api.protos |
524 | | - } |
525 | | - |
526 | | - if selective_gapic_settings.generate_omitted_as_internal: |
527 | | - for name, proto in api.protos.items(): |
528 | | - new_all_protos[name] = proto.with_internal_methods( |
529 | | - public_methods=selective_gapic_methods |
530 | | - ) |
531 | | - else: |
532 | | - all_resource_messages = collections.ChainMap( |
533 | | - *(proto.resource_messages for proto in protos.values()) |
534 | | - ) |
| 511 | + if package in api.all_library_settings: |
| 512 | + selective_gapic_settings = api.all_library_settings[ |
| 513 | + package |
| 514 | + ].python_settings.common.selective_gapic_generation |
| 515 | + |
| 516 | + selective_gapic_methods = set(selective_gapic_settings.methods) |
| 517 | + if selective_gapic_methods: |
| 518 | + # The list of explicitly allow-listed protos to generate, plus all |
| 519 | + # the proto dependencies regardless of the allow-list. |
| 520 | + # |
| 521 | + # Both selective GAPIC generation settings (omitting + internal) only alter |
| 522 | + # protos that are not dependencies, so we iterate over api.all_protos and copy |
| 523 | + # all dependencies as is here. |
| 524 | + new_all_protos = { |
| 525 | + k: v for k, v in api.all_protos.items() if k not in api.protos |
| 526 | + } |
535 | 527 |
|
536 | | - # Prepare a list of addresses to include in selective generation, |
537 | | - # then prune each Proto object. We look at metadata.Addresses, not objects, because |
538 | | - # objects that refer to the same thing in the proto are different Python objects |
539 | | - # in memory. |
540 | | - address_allowlist: Set["metadata.Address"] = set([]) |
541 | | - for proto in api.protos.values(): |
542 | | - proto.add_to_address_allowlist( |
543 | | - address_allowlist=address_allowlist, |
544 | | - method_allowlist=selective_gapic_methods, |
545 | | - resource_messages=all_resource_messages, |
| 528 | + if selective_gapic_settings.generate_omitted_as_internal: |
| 529 | + for name, proto in api.protos.items(): |
| 530 | + new_all_protos[name] = proto.with_internal_methods( |
| 531 | + public_methods=selective_gapic_methods |
| 532 | + ) |
| 533 | + else: |
| 534 | + all_resource_messages = collections.ChainMap( |
| 535 | + *(proto.resource_messages for proto in protos.values()) |
546 | 536 | ) |
547 | 537 |
|
548 | | - # We only prune services/messages/enums from protos that are not dependencies. |
549 | | - for name, proto in api.protos.items(): |
550 | | - proto_to_generate = ( |
551 | | - proto.prune_messages_for_selective_generation( |
552 | | - address_allowlist=address_allowlist |
| 538 | + # Prepare a list of addresses to include in selective generation, |
| 539 | + # then prune each Proto object. We look at metadata.Addresses, not objects, because |
| 540 | + # objects that refer to the same thing in the proto are different Python objects |
| 541 | + # in memory. |
| 542 | + address_allowlist: Set["metadata.Address"] = set([]) |
| 543 | + for proto in api.protos.values(): |
| 544 | + proto.add_to_address_allowlist( |
| 545 | + address_allowlist=address_allowlist, |
| 546 | + method_allowlist=selective_gapic_methods, |
| 547 | + resource_messages=all_resource_messages, |
553 | 548 | ) |
554 | | - ) |
555 | | - if proto_to_generate: |
556 | | - new_all_protos[name] = proto_to_generate |
557 | 549 |
|
558 | | - api = cls( |
559 | | - naming=naming, |
560 | | - all_protos=new_all_protos, |
561 | | - service_yaml_config=service_yaml_config, |
562 | | - gapic_version=gapic_version, |
563 | | - ) |
| 550 | + # We only prune services/messages/enums from protos that are not dependencies. |
| 551 | + for name, proto in api.protos.items(): |
| 552 | + proto_to_generate = ( |
| 553 | + proto.prune_messages_for_selective_generation( |
| 554 | + address_allowlist=address_allowlist |
| 555 | + ) |
| 556 | + ) |
| 557 | + if proto_to_generate: |
| 558 | + new_all_protos[name] = proto_to_generate |
| 559 | + |
| 560 | + api = cls( |
| 561 | + naming=naming, |
| 562 | + all_protos=new_all_protos, |
| 563 | + service_yaml_config=service_yaml_config, |
| 564 | + gapic_version=gapic_version, |
| 565 | + ) |
564 | 566 |
|
565 | | - return api |
| 567 | + return api |
566 | 568 |
|
567 | 569 | @cached_property |
568 | 570 | def enums(self) -> Mapping[str, wrappers.EnumType]: |
|
0 commit comments