class Gapic::Schema::Api

A representation of a full API.

@!attribute [r] files

@return [Array<File>] The files represented by this API.

@!attribute [r] services

@return [<Array<Service>] The services seen across all files in this
  API.

@!attribute [r] messages

@return [Array<Message>] The top level messages seen across all files
  in this API.

@!attribute [r] enums

@return [Array<Enum>] The top level enums seen across all files in
  this API.

Attributes

files[RW]
request[RW]

Public Class Methods

new(request, parameter_schema: nil, error_output: $stderr, configuration: nil) click to toggle source

Initializes an API object with the file descriptors that represent the API.

@param request [Google::Protobuf::Compiler::CodeGeneratorRequest]

The request object.

@param parameter_schema [Gapic::Schema::ParameterSchema]

The request parameters schema to use

@param error_output [IO] An IO to write any errors/warnings to. @param configuration [Hash] Optional override of configuration.

# File lib/gapic/schema/api.rb, line 54
def initialize request, parameter_schema: nil, error_output: $stderr, configuration: nil
  @request = request
  loader = Loader.new
  @files = request.proto_file.map do |fd|
    loader.load_file fd, request.file_to_generate.include?(fd.name)
  end
  @files.each { |f| f.parent = self }
  @configuration = configuration
  @resource_types = analyze_resources

  parameter_schema ||= Gapic::Generators::DefaultGeneratorParameters.default_schema
  @protoc_parameters = parse_parameter request.parameter, parameter_schema, error_output
  sanity_checks error_output
end

Public Instance Methods

common_services_for(delegate) click to toggle source

Given a service, find all common services that use it as a delegate.

# File lib/gapic/schema/api.rb, line 302
def common_services_for delegate
  @delegate_to_common ||= (configuration[:common_services] || {}).each_with_object({}) do |(c, d), mapping|
    (mapping[d] ||= []) << c
  end
  all_services = services
  @delegate_to_common.fetch(delegate.address.join("."), []).map do |addr|
    addr = addr.split "."
    all_services.find { |s| s.address == addr }
  end.compact.uniq
end
configuration() click to toggle source

Structured Hash representation of the configuration file. @return [Hash]

A Hash of the configuration values.
# File lib/gapic/schema/api.rb, line 207
def configuration
  @configuration ||= begin
    config_file = protoc_options["configuration"]
    config = config_file ? YAML.load_file(config_file) : {}
    protoc_options.each do |k, v|
      next if k == "configuration"
      branch = parse_key(key_to_str(k)).reverse.inject(v) { |m, s| { str_to_key(s) => m } }
      config = deep_merge config, branch
    end
    config
  end
end
containing_api() click to toggle source
# File lib/gapic/schema/api.rb, line 69
def containing_api
  self
end
containing_file() click to toggle source
# File lib/gapic/schema/api.rb, line 73
def containing_file
  nil
end
delegate_service_for(common) click to toggle source

Given a common service, return its delegate.

# File lib/gapic/schema/api.rb, line 314
def delegate_service_for common
  addr = (configuration[:common_services] || {})[common.address.join "."]
  return nil unless addr
  addr = addr.split "."
  services.find { |s| s.address == addr }
end
file_for(address) click to toggle source
# File lib/gapic/schema/api.rb, line 86
def file_for address
  address = address.join "." if address.is_a? Array
  matching_files = @files.select { |f| f.lookup address }
  matching_files.first
end
fix_file_path(str) click to toggle source
# File lib/gapic/schema/api.rb, line 96
def fix_file_path str
  str = String str
  return str if configuration[:overrides].nil?
  return str if configuration[:overrides][:file_path].nil?
  configuration[:overrides][:file_path].fetch str, str
end
fix_namespace(str) click to toggle source
# File lib/gapic/schema/api.rb, line 103
def fix_namespace str
  str = String str
  return str if configuration[:overrides].nil?
  return str if configuration[:overrides][:namespace].nil?
  configuration[:overrides][:namespace].fetch str, str
end
fix_service_name(str) click to toggle source
# File lib/gapic/schema/api.rb, line 110
def fix_service_name str
  str = String str
  return str if configuration[:overrides].nil?
  return str if configuration[:overrides][:service].nil?
  configuration[:overrides][:service].fetch str, str
end
generate_files() click to toggle source
# File lib/gapic/schema/api.rb, line 117
def generate_files
  @files.select(&:generate?)
end
generate_grpc_clients?() click to toggle source

Whether to generate GRPC clients

# File lib/gapic/schema/api.rb, line 243
def generate_grpc_clients?
  return true if configuration[:transports].nil?
  configuration[:transports].include? "grpc"
end
generate_metadata() click to toggle source

Whether to generate gapic metadata (drift manifest) file @return [Boolean]

# File lib/gapic/schema/api.rb, line 260
def generate_metadata
  configuration[:generate_metadata] ||= false
end
generate_path_helpers_output=(value) click to toggle source

Sets the generate_path_helpers_output parameter in the configuration

# File lib/gapic/schema/api.rb, line 226
def generate_path_helpers_output= value
  configuration[:generate_path_helpers_output] = value
end
generate_path_helpers_output?() click to toggle source

Whether to generate path helpers for output as well as input messages

# File lib/gapic/schema/api.rb, line 231
def generate_path_helpers_output?
  # if not set in configuration, false by default
  configuration[:generate_path_helpers_output] ||= false
end
generate_path_helpers_output_defined?() click to toggle source

Whether the generate_path_helpers_output parameter was given in the configuration

# File lib/gapic/schema/api.rb, line 221
def generate_path_helpers_output_defined?
  configuration.key? :generate_path_helpers_output
end
generate_rest_clients?() click to toggle source

Whether to generate REST clients

# File lib/gapic/schema/api.rb, line 237
def generate_rest_clients?
  return false if configuration[:transports].nil?
  configuration[:transports].include? "rest"
end
generate_standalone_snippets?() click to toggle source

Whether to generate standalone snippets

# File lib/gapic/schema/api.rb, line 249
def generate_standalone_snippets?
  configuration[:generate_standalone_snippets] ||= false
end
generate_yardoc_snippets?() click to toggle source

Whether to generate inline documentation snippets

# File lib/gapic/schema/api.rb, line 254
def generate_yardoc_snippets?
  configuration[:generate_yardoc_snippets] ||= false
end
grpc_service_config() click to toggle source

Parsed grpc service config

# File lib/gapic/schema/api.rb, line 292
def grpc_service_config
  @grpc_service_config ||= Gapic::GrpcServiceConfig::Parser.parse grpc_service_config_raw
end
grpc_service_config_raw() click to toggle source

Raw parsed json of the combined grpc service config files if provided or an empty hash if no config was provided

# File lib/gapic/schema/api.rb, line 281
def grpc_service_config_raw
  @grpc_service_config_raw ||= begin
    filenames = protoc_options["grpc_service_config"].to_s.split ";"
    filenames.inject({}) do |running_hash, filename|
      file_hash = JSON.parse ::File.read filename
      deep_merge running_hash, file_hash
    end
  end
end
incode_samples() click to toggle source

Structured representation of the inline samples configuration files. @return [Array<Hash>]

An array of the incode sample configuration hashes, sorted by sample_type.
# File lib/gapic/schema/api.rb, line 189
def incode_samples
  @incode_samples ||= begin
    supported_types = [
      "com.google.api.codegen.SampleConfigProto",
      "com.google.api.codegen.samplegen.v1p2.SampleConfigProto"
    ]
    samples.select { |sample_file| supported_types.include? sample_file["type"] }
           .select { |sample_file| sample_file["schema_version"] == "1.2.0" }
           .map { |sample_file| sample_file["samples"] }
           .flatten.compact
           .select { |sample_config| sample_config["sample_type"]&.start_with? "incode/" }
           .sort_by { |sample_config| sample_config["sample_type"] }
  end
end
lookup(address) click to toggle source
# File lib/gapic/schema/api.rb, line 77
def lookup address
  address = address.join "." if address.is_a? Array
  @files.each do |f|
    lookup = f.lookup address
    return lookup if lookup
  end
  nil
end
lookup_resource_type(resource_type) click to toggle source

Get a resource given its type string

# File lib/gapic/schema/api.rb, line 297
def lookup_resource_type resource_type
  @resource_types[resource_type]
end
messages() click to toggle source
# File lib/gapic/schema/api.rb, line 125
def messages
  @files.map(&:messages).flatten
end
override_proto_namespaces=(value) click to toggle source

Sets the override_proto_namespaces parameter in the configuration

# File lib/gapic/schema/api.rb, line 270
def override_proto_namespaces= value
  configuration[:override_proto_namespaces] = value
end
override_proto_namespaces?() click to toggle source

Whether namespace overrides apply to proto/grpc class references

# File lib/gapic/schema/api.rb, line 275
def override_proto_namespaces?
  configuration[:override_proto_namespaces] ||= false
end
override_proto_namespaces_defined?() click to toggle source

Whether the override_proto_namespaces parameter was given in the configuration

# File lib/gapic/schema/api.rb, line 265
def override_proto_namespaces_defined?
  configuration.key? :override_proto_namespaces
end
overrides_of(key) click to toggle source
# File lib/gapic/schema/api.rb, line 92
def overrides_of key
  configuration&.fetch(:overrides, nil)&.fetch(key, nil) || {}
end
protoc_options() click to toggle source

Structured Hash representation of the parameter values. @return [Hash]

# File lib/gapic/schema/api.rb, line 131
def protoc_options
  @protoc_options ||= begin
    result = {}
    @protoc_parameters.each do |parameter|
      result[str_to_key(parameter.config_name)] = parameter.config_value
    end
    result
  end
end
protoc_parameter() click to toggle source

Reconstructed string representation of the protoc parameters @return [String]

# File lib/gapic/schema/api.rb, line 143
def protoc_parameter
  Gapic::Schema::RequestParamParser.reconstruct_parameters_string @protoc_parameters
end
samples() click to toggle source

Structured representation of the samples configuration files. @return [Array<Hash>]

An array of the sample file hashes.
# File lib/gapic/schema/api.rb, line 150
def samples
  @samples ||= protoc_options["samples"].to_s.split(";").flat_map do |sample_path|
    YAML.load_file sample_path
  end.compact
end
services() click to toggle source
# File lib/gapic/schema/api.rb, line 121
def services
  @files.map(&:services).flatten
end
standalone_samples() click to toggle source

Structured representation of the standalone samples configuration files. @return [Array<Hash>]

An array of the standalone sample configuration hashes.
# File lib/gapic/schema/api.rb, line 159
def standalone_samples
  @standalone_samples ||= begin
    supported_types = [
      "com.google.api.codegen.SampleConfigProto",
      "com.google.api.codegen.samplegen.v1p2.SampleConfigProto"
    ]
    supported_sample_types = [nil, "standalone"]
    samples.select { |sample_file| supported_types.include? sample_file["type"] }
           .select { |sample_file| sample_file["schema_version"] == "1.2.0" }
           .map { |sample_file| sample_file["samples"] }
           .flatten.compact
           .select { |sample_config| supported_sample_types.include? sample_config["sample_type"] }
  end
end
standalone_test_samples() click to toggle source

Structured representation of the standalone test samples configuration files. @return [Array<Hash>]

An array of the standalone sample configuration hashes.
# File lib/gapic/schema/api.rb, line 177
def standalone_test_samples
  @standalone_test_samples ||= begin
    test_samples = samples.select { |sample| sample["type"] == "test/samples" }
    test_samples.select { |sample| sample["schema_version"] == "1" || sample["schema_version"] == 1 }
                .map { |sample| sample["samples"] }
                .flatten.compact
  end
end
wrapper_gem_name_override() click to toggle source

An override for the wrapper gem name in the configuration @return [String, nil]

# File lib/gapic/schema/api.rb, line 332
def wrapper_gem_name_override
  return nil unless wrapper_gem_name_override?
  return nil if configuration[:overrides][:wrapper_gem_name].nil?

  wrapper_name_config = configuration[:overrides][:wrapper_gem_name].strip
  return nil if wrapper_name_config.empty?

  wrapper_name_config
end
wrapper_gem_name_override?() click to toggle source

Whether configuration has an override for the wrapper gem name @return [Boolean]

# File lib/gapic/schema/api.rb, line 324
def wrapper_gem_name_override?
  configuration.key?(:overrides) &&
    configuration[:overrides].key?(:wrapper_gem_name)
end

Private Instance Methods

analyze_resources() click to toggle source

Does a pre-analysis of all resources defined in the job. This has two effects:

  • Side effect: each resource has its parent_resources field set.

  • A mapping from resource type to resource wrapper is returned.

# File lib/gapic/schema/api.rb, line 360
def analyze_resources
  # In order to set parent_resources, we first populate a mapping from
  # parsed pattern to resources that use it (in the patterns variable).
  # Note that there may be multiple resources associated with a pattern.
  # (This is uncommon, but one example is monitoring v3 which uses
  # "projects/*" for its workspace type as well as inheriting the common
  # project type. We thus map each pattern to an array of resources.)
  # Constructing the patterns mapping is done in one pass along with
  # populating the type mapping (which maps only to single resources.)
  # Then, we go through all resources again, get each's expected parent
  # patterns, and anything that shows up in the patterns mapping is taken
  # to be a parent.
  types = {}
  patterns = {}
  @files.each do |file|
    file.resources.each { |resource| populate_resource_lookups resource, types, patterns }
    file.messages.each { |message| populate_message_resource_lookups message, types, patterns }
  end
  types.each do |_type, resource|
    parents = resource.parsed_parent_patterns
                      .flat_map { |pat| Array(patterns[pat]) }
                      .uniq
    resource.parent_resources.replace parents
  end
  types
end
deep_merge(left, right) click to toggle source
# File lib/gapic/schema/api.rb, line 437
def deep_merge left, right
  left.merge right do |_k, lt, rt|
    if lt.is_a?(Hash) && rt.is_a?(Hash)
      deep_merge lt, rt
    elsif lt.is_a?(Array) && rt.is_a?(Array)
      lt + rt
    else
      rt
    end
  end
end
key_to_str(key) click to toggle source
# File lib/gapic/schema/api.rb, line 433
def key_to_str key
  key.is_a?(::Symbol) ? ":#{key}" : key.to_s
end
parse_key(str) click to toggle source

split the string on periods, but map backslash-escaped periods to literal periods.

# File lib/gapic/schema/api.rb, line 414
def parse_key str
  str.scan(/\.|\\.|[^.\\]+/)
     .each_with_object([String.new]) do |tok, arr|
       if tok == "."
         arr.append String.new
       elsif tok.start_with? "\\"
         arr.last << tok[1]
       else
         arr.last << tok
       end
       arr
     end
end
parse_parameter(str, parameter_schema, error_output) click to toggle source

Parse a comma-delimited list of equals-delimited lists of strings, while mapping backslash-escaped commas and equal signs to literal characters. @param str [String] @param error_output [IO] Stream to write outputs to. @return [Array<Gapic::Schema::RequestParameter>]

# File lib/gapic/schema/api.rb, line 406
def parse_parameter str, parameter_schema, error_output
  Gapic::Schema::RequestParamParser.parse_parameters_string str,
                                                            param_schema: parameter_schema,
                                                            error_output: error_output
end
populate_message_resource_lookups(message, types, patterns) click to toggle source
# File lib/gapic/schema/api.rb, line 394
def populate_message_resource_lookups message, types, patterns
  populate_resource_lookups message.resource, types, patterns if message.resource
  message.nested_messages.each do |nested|
    populate_message_resource_lookups nested, types, patterns
  end
end
populate_resource_lookups(resource, types, patterns) click to toggle source
# File lib/gapic/schema/api.rb, line 387
def populate_resource_lookups resource, types, patterns
  types[resource.type] = resource
  resource.parsed_patterns.each do |pat|
    ((patterns[pat] ||= []) << resource).uniq!
  end
end
sanity_checks(output) click to toggle source

Perform a variety of sanity checks on the data, and prints errors to the given output as appropriate.

@param output [IO] Stream to write outputs to.

# File lib/gapic/schema/api.rb, line 348
def sanity_checks output
  addrs = services.map { |service| service.address.join "." }
  configuration[:common_services]&.each do |k, v|
    output.puts "WARNING: configured common service #{k} is not present" unless addrs.include? k
    output.puts "WARNING: configured common service delegate #{v} is not present" unless addrs.include? v
  end
end
str_to_key(str) click to toggle source
# File lib/gapic/schema/api.rb, line 428
def str_to_key str
  str = str.to_s
  str.start_with?(":") ? str[1..-1].to_sym : str
end