Class: Gapic::Schema::Loader

Inherits:
Object
  • Object
show all
Defined in:
lib/gapic/schema/loader.rb

Overview

Loader

Constant Summary collapse

FILE_EXTENSION_NAMES =
{
  "google.api.resource_definition" => [1053, ::Google::Api::ResourceDescriptor, :repeated]
}.freeze
MESSAGE_EXTENSION_NAMES =
{
  "google.api.resource" => [1053, ::Google::Api::ResourceDescriptor]
}.freeze

Instance Method Summary collapse

Constructor Details

#initializeLoader

Initializes the loader



33
34
35
36
# File 'lib/gapic/schema/loader.rb', line 33

def initialize
  @prior_messages = []
  @prior_enums = []
end

Instance Method Details

#cached_enum(type_name) ⇒ Enum | nil

Retrieves an Enum if it has been seen before.

Parameters:

  • type_name (String)

    the type name of the enum.

Returns:

  • (Enum | nil)

    The enum if it has already been seen or nil if no enum can be found.



281
282
283
# File 'lib/gapic/schema/loader.rb', line 281

def cached_enum type_name
  cached_obj @prior_enums, type_name
end

#cached_message(type_name) ⇒ Enum | nil

Retrieves a Message if it has been seen before.

Parameters:

  • type_name (String)

    the type name of the message.

Returns:

  • (Enum | nil)

    The message if it has already been seen or nil if no message can be found.



290
291
292
# File 'lib/gapic/schema/loader.rb', line 290

def cached_message type_name
  cached_obj @prior_messages, type_name
end

#load_enum(registry, descriptor, address, docs, path) ⇒ Enum

Loads an enum.

Parameters:

  • descriptor (Google::Protobuf::EnumDescriptorProto)

    the descriptor of this enum.

  • address (Enumerable<String>)

    The address of the parent.

  • docs (Hash<Enumerable<Integer>, Google::Protobuf::SourceCodeInfo::Location>)

    A mapping of a path to the docs. See Proto#docs for more info.

  • path (Enumerable<Integer>)

    The current path. This is used to get the docs for a proto. See Proto#docs for more info.

Returns:

  • (Enum)

    The loaded enum.



132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/gapic/schema/loader.rb', line 132

def load_enum registry, descriptor, address, docs, path
  # Update Address.
  address = address.clone << descriptor.name

  # Load Enum Values
  values = (descriptor.value || []).each_with_index.map do |value, i|
    load_enum_value registry, value, address, docs, path + [2, i]
  end

  # Construct, cache and return enum.
  enum = Enum.new descriptor, address, docs[path], values
  @prior_enums << enum
  add_to_registry registry, address, enum
end

#load_enum_value(registry, descriptor, address, docs, path) ⇒ EnumValue

Loads an enum value.

Parameters:

  • descriptor (Google::Protobuf::EnumValueDescriptorProto)

    the descriptor of this enum value.

  • address (Enumerable<String>)

    the address of the parent.

  • docs (Hash<Enumerable<Integer>, Google::Protobuf::SourceCodeInfo::Location>)

    A mapping of a path to the docs. See Proto#docs for more info.

  • path (Enumerable<Integer>)

    The current path. This is used to get the docs for a proto. See Proto#docs for more info.

Returns:



158
159
160
161
162
163
164
165
# File 'lib/gapic/schema/loader.rb', line 158

def load_enum_value registry, descriptor, address, docs, path
  # Update Address.
  address = address.clone << descriptor.name

  # Construct and return value.
  enum_value = EnumValue.new descriptor, address, docs[path]
  add_to_registry registry, address, enum_value
end

#load_field(registry, descriptor, address, docs, path) ⇒ Field

Loads a field.

Parameters:

  • descriptor (Google::Protobuf::FieldDescriptorProto)

    the descriptor of this field.

  • address (Enumerable<String>)

    The address of the parent.

  • docs (Hash<Enumerable<Integer>, Google::Protobuf::SourceCodeInfo::Location>)

    A mapping of a path to the docs. See Proto#docs for more info.

  • path (Enumerable<Integer>)

    The current path. This is used to get the docs for a proto. See Proto#docs for more info.

Returns:

  • (Field)

    The loaded field.



220
221
222
223
224
225
226
227
228
# File 'lib/gapic/schema/loader.rb', line 220

def load_field registry, descriptor, address, docs, path
  # Update address.
  address = address.clone << descriptor.name

  # Construct and return the field.
  field = Field.new(descriptor, address, docs[path],
                    cached_message(descriptor.type_name), cached_enum(descriptor.type_name))
  add_to_registry registry, address, field
end

#load_file(file_descriptor, file_to_generate) ⇒ Gapic::Schema::File

Loads a file.

Parameters:

  • file_descriptor (Google::Protobuf::FileDescriptorProto)

    the descriptor of the proto file.

  • file_to_generate (Boolean)

    Whether this file is to be generated.

Returns:



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/gapic/schema/loader.rb', line 53

def load_file file_descriptor, file_to_generate
  # Setup.
  address = file_descriptor.package.split "."
  path = []
  registry = {}

  # Load the docs.
  location = file_descriptor.source_code_info.location || []
  docs = location.each_with_object({}) { |l, ans| ans[l.path.to_a] = l }

  # Load top-level enums.
  enums = (file_descriptor.enum_type || []).each_with_index.map do |e, i|
    load_enum registry, e, address, docs, [5, i]
  end

  # Load top-level messages.
  messages = (file_descriptor.message_type || []).each_with_index.map do |m, i|
    load_message registry, m, address, docs, [4, i]
  end
  messages.each(&method(:update_fields!))

  # Load services.
  services = (file_descriptor.service || []).each_with_index.map do |s, i|
    load_service registry, s, address, docs, [6, i]
  end

  # Load top-level resources
  option_extensions = ProtoTools.parse_options_extensions file_descriptor.options, FILE_EXTENSION_NAMES
  resource_descriptors = option_extensions["google.api.resource_definition"]
  resources = Array(resource_descriptors).map { |descriptor| Resource.new descriptor }

  # Construct and return the file.
  File.new file_descriptor, address, docs[path], messages, enums,
           services, resources, file_to_generate, registry
end

#load_message(registry, descriptor, address, docs, path) ⇒ Message

Loads a message. As a side effect, this alters @messages and @enums with the nested messages that are found.

Parameters:

  • descriptor (Google::Protobuf::DescriptorProto)

    the descriptor of this message.

  • address (Enumerable<String>)

    the address of the parent.

  • docs (Hash<Enumerable<Integer>, Google::Protobuf::SourceCodeInfo::Location>)

    A mapping of a path to the docs. See Proto#docs for more info.

  • path (Enumerable<Integer>)

    The current path. This is used to get the docs for a proto. See Proto#docs for more info.

Returns:

  • (Message)

    The loaded message.



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/gapic/schema/loader.rb', line 179

def load_message registry, descriptor, address, docs, path
  # Update Address.
  address = address.clone << descriptor.name

  # Load Children
  nested_messages = (descriptor.nested_type || []).each_with_index.map do |m, i|
    load_message registry, m, address, docs, path + [3, i]
  end
  nested_enums = (descriptor.enum_type || []).each_with_index.map do |e, i|
    load_enum registry, e, address, docs, path + [4, i]
  end
  fields = (descriptor.field || []).each_with_index.map do |f, i|
    load_field registry, f, address, docs, path + [2, i]
  end
  fields.each { |field| field.populate_oneof_siblings! fields }
  extensions = (descriptor.extension || []).each_with_index.map do |e, i|
    load_field registry, e, address, docs, path + [6, i]
  end

  option_extensions = ProtoTools.parse_options_extensions descriptor.options, MESSAGE_EXTENSION_NAMES
  resource_descriptor = option_extensions["google.api.resource"]
  resource = resource_descriptor ? Resource.new(resource_descriptor) : nil

  # Construct, cache, and return.
  msg = Message.new(descriptor, address, docs[path], fields, extensions,
                    resource, nested_messages, nested_enums)
  @prior_messages << msg
  add_to_registry registry, address, msg
end

#load_method(registry, descriptor, address, docs, path) ⇒ Method

Loads a method.

Parameters:

  • descriptor (Google::Protobuf::MethodDescriptorProto)

    the descriptor of this service.

  • address (Enumerable<String>)

    The address of the parent.

  • docs (Hash<Enumerable<Integer>, Google::Protobuf::SourceCodeInfo::Location>)

    A mapping of a path to the docs. See Proto#docs for more info.

  • path (Enumerable<Integer>)

    The current path. This is used to get the docs for a proto. See Proto#docs for more info.

Returns:

  • (Method)

    The loaded method.



266
267
268
269
270
271
272
273
274
# File 'lib/gapic/schema/loader.rb', line 266

def load_method registry, descriptor, address, docs, path
  # Update the address.
  address = address.clone << descriptor.name

  # Construct and return the method.
  method = Method.new(descriptor, address, docs[path],
                      cached_message(descriptor.input_type), cached_message(descriptor.output_type))
  add_to_registry registry, address, method
end

#load_service(registry, descriptor, address, docs, path) ⇒ Service

Loads a service.

Parameters:

  • descriptor (Google::Protobuf::ServiceDescriptorProto)

    the descriptor of this service.

  • address (Enumerable<String>)

    The address of the parent.

  • docs (Hash<Enumerable<Integer>, Google::Protobuf::SourceCodeInfo::Location>)

    A mapping of a path to the docs. See Proto#docs for more info.

  • path (Enumerable<Integer>)

    The current path. This is used to get the docs for a proto. See Proto#docs for more info.

Returns:

  • (Service)

    The loaded service.



241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/gapic/schema/loader.rb', line 241

def load_service registry, descriptor, address, docs, path
  # Update the address.
  address = address.clone << descriptor.name

  # Load children
  methods = (descriptor["method"] || descriptor.method || []).each_with_index.map do |m, i|
    load_method registry, m, address, docs, path + [2, i]
  end

  # Construct and return the service.
  service = Service.new descriptor, address, docs[path], methods
  add_to_registry registry, address, service
end

#load_snippet_configs(path) ⇒ Array< Google::Cloud::Tools::SnippetGen::ConfigLanguage::V1::SnippetConfig>

Loads snippet configs from the given directory

Parameters:

  • path (String)

    Directory to search for snippet config files

Returns:



96
97
98
99
100
101
102
103
104
105
106
# File 'lib/gapic/schema/loader.rb', line 96

def load_snippet_configs path
  return [] unless path
  Dir.chdir path do
    Dir.glob("**/*.json").map do |file_path|
      json = JSON.load_file file_path
      proto = Google::Cloud::Tools::SnippetGen::ConfigLanguage::V1::SnippetConfig.new underscore_keys json
      proto.json_representation = json
      proto
    end
  end
end

#update_fields!(message) ⇒ Object

Updates the fields of a message and it's nested messages.

Parameters:

  • message (Message)

    the message whose fields and nested messages to update.



112
113
114
115
116
117
118
119
# File 'lib/gapic/schema/loader.rb', line 112

def update_fields! message
  message.nested_messages.each(&method(:update_fields!))
  non_primitives = message.fields.reject { |f| f.type_name.empty? }
  non_primitives.each do |f|
    f.message ||= cached_message f.type_name
    f.enum ||= cached_enum f.type_name
  end
end