Class: ElasticGraph::ProtoIngestion::SchemaDefinition::Schema

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
elasticgraph-proto_ingestion/lib/elastic_graph/proto_ingestion/schema_definition/schema.rb

Overview

Builds a proto2 or proto3 schema string from an ElasticGraph schema definition.

Constant Summary collapse

SUPPORTED_SYNTAXES =

Protobuf syntaxes this generator can emit.

%w[proto2 proto3].freeze
DEFAULT_SYNTAX =

The protobuf syntax emitted when the schema does not configure one.

"proto3"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(state:, all_types:, ingestion_state:, ingestible_types_by_name:) ⇒ Schema

Returns a new instance of Schema.

Parameters:

  • state (ElasticGraph::SchemaDefinition::State)
  • all_types (Array<ElasticGraph::SchemaDefinition::SchemaElements::graphQLType>)
  • ingestion_state (ProtoIngestionState)

    this extension's configured schema definition state

  • ingestible_types_by_name (Hash<String, Object>)

    ingestible schema types, including abstract types



68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'elasticgraph-proto_ingestion/lib/elastic_graph/proto_ingestion/schema_definition/schema.rb', line 68

def initialize(
  state:,
  all_types:,
  ingestion_state:,
  ingestible_types_by_name:
)
  @state = state
  @all_types = all_types
  @ingestible_types_by_name = ingestible_types_by_name
  @package_name = ingestion_state.package_name
  @syntax = self.class.validate_syntax(ingestion_state.syntax)
  @header_lines = self.class.validate_header_lines(ingestion_state.header_lines)
  @field_number_mappings = FieldNumberMappings.from_parsed_yaml(ingestion_state.field_number_mappings)
end

Class Method Details

.validate_header_lines(header_lines) ⇒ Array<String>

Validates configured header_lines, as validate_syntax does for a syntax.

Each element renders as its own line, so a newline in one element would silently produce more lines than the schema asked for.

Parameters:

  • header_lines (Array<String>)

Returns:

  • (Array<String>)


51
52
53
54
55
56
57
58
59
60
61
62
# File 'elasticgraph-proto_ingestion/lib/elastic_graph/proto_ingestion/schema_definition/schema.rb', line 51

def self.validate_header_lines(header_lines)
  unless header_lines.is_a?(::Array) && header_lines.all?(::String)
    raise Errors::SchemaError, "`header_lines` must be an Array of Strings, got: #{header_lines.inspect}"
  end

  if (multi_line = header_lines.grep(/\n/)).any?
    raise Errors::SchemaError, "`header_lines` must not contain newlines, but got: #{multi_line.inspect}. " \
      "Pass one Array element per line."
  end

  header_lines
end

.validate_syntax(syntax) ⇒ String

Normalizes a configured syntax to one of SUPPORTED_SYNTAXES.

Both the proto_schema_artifacts API and this class validate through here so that a syntax is checked exactly once no matter which entry point supplies it.

Parameters:

  • syntax (Symbol, String)

Returns:

  • (String)


36
37
38
39
40
41
42
# File 'elasticgraph-proto_ingestion/lib/elastic_graph/proto_ingestion/schema_definition/schema.rb', line 36

def self.validate_syntax(syntax)
  syntax.to_s.tap do |normalized|
    unless SUPPORTED_SYNTAXES.include?(normalized)
      raise Errors::SchemaError, "`syntax` must be one of #{SUPPORTED_SYNTAXES.inspect}, got: #{syntax.inspect}"
    end
  end
end

Instance Method Details

#field_label_prefix(repeated:) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the label prefix (including its trailing space) that a field declaration needs under the configured syntax, or an empty string when the field takes no label.

Non-repeated fields use optional in both syntaxes so that absence is distinct from an explicitly supplied zero, false, or empty string. oneof alternatives never get a label under either syntax -- protoc rejects one -- so the oneof renderer in ObjectInterfaceAndUnionExtension does not call this.



139
140
141
142
# File 'elasticgraph-proto_ingestion/lib/elastic_graph/proto_ingestion/schema_definition/schema.rb', line 139

def field_label_prefix(repeated:)
  return "repeated " if repeated
  "optional "
end

#field_number_for(message_name:, type_name:, public_field_name:) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the stable protobuf number for a message field.



113
114
115
116
117
118
119
# File 'elasticgraph-proto_ingestion/lib/elastic_graph/proto_ingestion/schema_definition/schema.rb', line 113

def field_number_for(message_name:, type_name:, public_field_name:)
  @field_number_mappings.field_number_for(
    message_name: message_name,
    public_field_name: public_field_name,
    previous_field_names: previous_field_names_for(type_name, public_field_name)
  )
end

#field_number_mappings_for_artifactHash<String, Object>

Exposes the field-number and enum-value-number mappings for writing to artifact YAML.

Returns:

  • (Hash<String, Object>)


106
107
108
# File 'elasticgraph-proto_ingestion/lib/elastic_graph/proto_ingestion/schema_definition/schema.rb', line 106

def field_number_mappings_for_artifact
  @field_number_mappings.to_dumpable_hash
end

#to_protoString

Renders the schema as a valid file in the configured syntax.

Returns:

  • (String)


86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'elasticgraph-proto_ingestion/lib/elastic_graph/proto_ingestion/schema_definition/schema.rb', line 86

def to_proto
  types = proto_types
  return "" if types.empty?

  validate_unique_enum_value_prefixes(types)

  sections = [
    %(syntax = "#{@syntax}";),
    "package #{@package_name};",
    *render_header_lines,
    *render_imports(types),
    render_definitions(types)
  ]

  sections.join("\n\n") + "\n"
end